2012-07-27 14 views
12

Como siempre, cuando Apple actualiza OS X, el último XCode 4.4 volca el SDK anterior (10.6) y necesito usar 10.7 SDK (o 10.8 I supongo) y establecer mi objetivo de despliegue en 10.6 para mantener la compatibilidad.Mac SDK: utilizando el último SDK pero asegurando la compatibilidad con el destino de implementación anterior

Prefiero vincularme al SDK antiguo porque sé que no puedo, por error, introducir llamadas a API que aún no existen. Algo que me encontré haciendo regularmente la última vez que probé el enfoque inverso.

Lo que me encuentro haciendo es usar la función de completar código en XCode para elegir la llamada "correcta" para una clase simple como NSWorkspace, luego todo funciona bien durante el desarrollo, me olvido y cuando lanzo un nuevo versión: Kaboum! Toda la aplicación explota en versiones anteriores de OS X en tiempo de ejecución; a menudo en esos lugares difíciles de alcanzar :-)

O al menos esta era la situación para mí hace unos años.

Seguramente, por ahora no hay una manera de cualquiera:

  • asegurándose de que no se introducen llamadas a la API que aún no están disponibles en su destino de implementación, aunque a pesar de que se definen en el SDK

  • detectar este tipo de llamadas durante la construcción o el análisis estático tiempo

estoy seguro de que he perdido algo, en algún lugar a lo largo de la línea .. por favor me ilumine!

Saludos,

Frank

+0

que tenía una pregunta similar en relación con iOS, pero muchos puntos deben ser similares. http://stackoverflow.com/questions/19111934/get-xcode-5-to-warn-about-new-api-calls/19131877 – Rivera

Respuesta

6

Seguramente, por ahora no hay una manera de cualquiera:

  • asegurándose de que no se introducen llamadas a la API que aún no están disponibles en su destino de implementación, aunque a pesar de que se definen en el SDK

  • detectar este tipo de llamadas durante la construcción o el análisis estático tiempo

No, no hay. Sí, debes abrir un radar (bugreport.apple.com) contra él. Si lo desea, puede engañar a la mía: rdar://11985733

Sí, la única solución viable, a pesar de la recomendación de Apple, es copiar los SDK antiguos y vincularlos.

Pasé bastante tiempo hablando con el equipo de Xcode sobre este tema en la WWDC 2012. Aceptaron que no funciona. Actualmente no hay un plan para arreglarlo. La escalada del radar es la forma en que influimos en Apple en estas cosas.

2

general estoy copio SDK desde versiones anteriores a la nueva uno para que el compilador me va a Blain si uso algo que no es compatible.

También usted puede simplemente mirar Ayuda rápida al llamar a algunos métodos que usted no está seguro acerca de, al igual que en la pantalla se puede ver que launchApplicationAtURL método sólo está disponible a partir de 10,6

enter image description here

+0

Lo siento, aparentemente no puedo dividir la recompensa .. gracias por su ayuda! –

2

También he tenido este molesto problema en iOS. En realidad, es aún más molesto para iOS ya que el usuario tiene que sincronizar su dispositivo con iTunes y habilitar el envío de informes de fallos antes de que se envíe el informe de fallos a diferencia de Mac OS X donde no es necesario que haga todo eso. Recientemente, logré agregar una verificación en tiempo de compilación para verificar API contra versiones anteriores del SDK. Primero explicaré cómo lo hice para iOS primero y luego intentaré ayudarte a adaptar esta técnica para Mac OS X. No codifico mucho para Mac atm, así que solo puedo guiarte en la dirección correcta desde mi experiencia. con iOS, pero probaré mis sugerencias más tarde hoy una vez que regrese del trabajo y dé una respuesta definitiva.


Así que aquí es lo que hice para iOS:

primero tenía que conseguir el mayor Simulador SDK quería obtener. Podría obtenerlo fácilmente descargando versiones anteriores de Xcode (no 4) que incluían el SDK necesario.

Luego tuve que instalar el SDK. Esto no fue muy difícil, así que no voy a explicar mucho aquí. Pero los SDK se almacenan en la carpeta Packages. Esta carpeta es claramente visible en versiones anteriores de Xcode 3, pero está oculta en versiones posteriores. Puede abrirlo de todos modos a través de la Terminal. Además, después del cambio en Xcode 4.3 donde se movió la carpeta Developer dentro de Xcode.app, tuve que instalar el SDK en una carpeta tmp y mover el SDK a Xcode.app usted mismo. Entonces necesitaría reiniciar Xcode si lo tuviera abierto.

Después de eso, dupliqué mi configuración debug en su proyecto y la denominé, en mi caso, algo así como iOS 4.3 API Check o algo así - en realidad no importa. Luego cambié el SDK base de esta nueva configuración al viejo SDK que instalé. El SDK que instalé no estaba en la lista, así que tuve que seleccionar other e ingresar, nuevamente en mi caso, iphonesimulator4.3.

Finalmente, cuando necesité comprobar contra versiones anteriores del SDK, cambié la configuración para el Run <appname>.app en mi esquema de proyecto a la configuración iOS 4.3 API Check. Y ahí vamos, una verificación en tiempo de compilación contra iOS 4.3.


En Mac OS X, estoy seguro de que puede lograr el mismo objetivo con este mismo método. No hay simuladores para el SDK de Mac, así que creo que el SDK normal funcionará para esto. En cuanto a obtener el SDK más antiguo, si tiene Xcode 4.2 todavía instalado (después de que Xcode 4.3 lo haya cambiado para que la carpeta Developer esté dentro de Xcode.app), entonces debería encontrar allí el SDK 10.6. Si no lo hace, me imagino que Apple tiene una cosa similar a iOS donde las descargas de SDK están disponibles en el Dev Center o en algún lugar en Internet ...

En cuanto a la configuración del SDK base, si no es en la lista, entonces creo que el nombre es MacOSX10.6 o la versión que quieras.

Todo lo demás debería ser igual, pero como mencioné anteriormente, probaré este método más tarde y editaré mi respuesta para dar una respuesta más definitiva, pero me imagino que este método funcionaría para Mac SDK.

+0

Lo siento, aparentemente no puedo dividir la recompensa .. gracias por su ayuda! –

0

Comprobo mi código pirateando la disponibilidad para obtener que el compilador señale los símbolos de enlace débil como advertencias/errores.En mi encarnación actual (Xcode 5/llvm), estoy usando el código a continuación. Advierte cada vez que uso un símbolo introducido en iOS 6.0 o posterior. Creo que es bastante auto explicativo. Parece que las macros necesitan actualizarse en todas y cada una de las actualizaciones del SDK, así que pise con cuidado. Oh, y también pierdes advertencias de desaprobación, así que solo uso esto de vez en cuando para volver a verificar mi código condicional.

#undef __NSi_6_0 
#define __NSi_6_0 deprecated=1.0 
#undef __NSi_6_1 
#define __NSi_6_1 deprecated=1.0 
#undef __NSi_7_0 
#define __NSi_7_0 deprecated=1.0 

#undef __NSd_6_0 
#define __NSd_6_0 
#undef __NSd_6_1 
#define __NSd_6_1 
#undef __NSd_7_0 
#define __NSd_7_0 

Ver también http://iphone.m20.nl/wp/2013/10/xcode-5-and-flagging-weak-linked-unavailable-symbols-from-a-newer-sdk/

+0

En realidad, he ido por el camino de copiar el antiguo SDK en Xcode 5, que funciona bien para 10.7. –

+0

También he descubierto la herramienta vinculada: http://www.deploymateapp.com que le permite verificar su código para compatibilidad con versiones anteriores. –

+0

Usar un SDK anterior está bien, por supuesto. Mi enfoque es útil si desea usar funciones del nuevo sistema operativo de forma selectiva. Supongo que deploymate hace algo similar. –

0

i asumió también que el compilador me va a advertir sobre "demasiado nuevo" uso de la API de la versión del sistema operativo de destino del despliegue. pero resultó que el compilador no lo advierte por defecto. uno de los motivos podría ser que aún podría utilizar la nueva API verificando la disponibilidad durante el tiempo de ejecución con "respondsToSelector:", por ejemplo, en una versión de sistema operativo más nueva, incluso cuando la versión de destino de implementación era anterior. Debería agregar la opción del compilador -Wactial-availability que está disponible en Xcode 7.3+ (por confirmar) para obtener el mensaje de advertencia "warning: 'something' is partial: introduced in macOS 10.x".

en MacOS 10.12.3 con Xcode 8.2.1:

$ cat foo.m 
#include <Foundation/Foundation.h> 

BOOL foo() 
{ 
    return [@"foo" containsString:@"bar"]; 
} 

$ cc -mmacosx-version-min=10.9 -Wpartial-availability foo.m -c -o foo.o 
foo.m:5:20: warning: 'containsString:' is partial: introduced in macOS 10.10 [-Wpartial-availability] 
    return [@"foo" containsString:@"bar"]; 
       ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSString.h:132:1: note: 
     'containsString:' has been explicitly marked partial here 
- (BOOL)containsString:(NSString *)str NS_AVAILABLE(10_10, 8_0); 
^ 
foo.m:5:20: note: explicitly redeclare 'containsString:' to silence this warning 
    return [@"foo" containsString:@"bar"]; 
       ^
1 warning generated. 

véase también: Is there a way for XCode to warn about new API calls?

Cuestiones relacionadas