swiftify objective objc for convert objective-c swift

objective c - objc - Cómo anotar las API de Objective-C para su uso en Swift(por ejemplo, tipos de devolución)



swift 3 to swift 4 converter (2)

Xcode 6.3 / Swift 1.2

Xcode 6.3 agregó soporte oficial para anotar la nulabilidad en Objective-C.

Nulabilidad

La nulabilidad de un valor se puede declarar anotando el tipo con las palabras clave __nullable , __nonnull y __null_unspecified (el valor predeterminado). En propiedades y métodos, las palabras clave son nullable , no nonnull y null_unspecified .

Ejemplos de las notas de lanzamiento de Xcode

- (void)registerNib:(nonnull UINib *)nib forCellReuseIdentifier:(nonnull NSString *)identifier; - (nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull NSIndexPath)indexPath; @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;

Cambiando el valor predeterminado

null_unspecified (que se traduce a T! ) es el valor predeterminado para todo el código existente. Una característica útil es la capacidad de cambiar el valor predeterminado para las secciones de su API.

NS_ASSUME_NONNULL_BEGIN // nonnull is the default here NS_ASSUME_NONNULL_END

Esto elimina una gran cantidad de ruido, ya que los métodos que aceptan y manejan cero generalmente son la excepción, no la regla. Personalmente, usaría esto para todas las API auditadas.

null_resettable

null_resettable es una anotación adicional que se usa para el caso poco común en el que puede establecer una propiedad en nulo, pero nunca será nulo (porque se restablece a un valor predeterminado).

@property (nonatomic, retain, null_resettable) UIColor *tintColor;

Personalmente, evitaría este comportamiento para el nuevo código. La naturaleza híbrida de tales propiedades no es un buen ajuste para Swift.

Xcode 7 / Swift 2 (Beta)

Xcode 7 agrega soporte para anotar tipos genéricos en Objective-C.

Anotaciones de tipo genérico para colecciones.

NSArray , NSSet y NSDictionary (que se NSSet automáticamente a la Array , el Set y el Dictionary Swift se pueden anotar con el tipo de su contenido).

@property NSArray<NSString *> *stringArray; @property NSSet<NSString *> *stringSet; @property NSDictionary<NSString *, NSString *> *stringDict;

También está la palabra clave __kindof que le dice al compilador de Objective-C que sea menos estricto y que permita el downcasting. Pero no afecta al lado Swift.

Anotaciones de tipo genérico para clases personalizadas.

@interface MyArray1<__covariant T> : NSObject - (void)addObject:(T)object; @end @interface MyArray2<__covariant T : NSObject *> : NSObject - (void)addObject:(T)object; @end @interface MyArray3<__covariant T : id<NSCopying>> : NSObject - (void)addObject:(T)object; @end

La @implementation no sabe acerca de T y usa id / NSObject * / id<NSCopying> como siempre lo hizo.

De acuerdo con las notas de la versión de Xcode, Apple ha estado "auditando" sus API existentes para eliminar las opciones implícitamente desenvueltas. Eso significa que en lugar de T! , sus APIs devolverán T o T? donde corresponda.

¿Dónde hacen esto? ¿Cómo puedo anotar / envolver mi código existente de Objective-C (especialmente las bibliotecas) para que sea más fácil de usar desde Swift?


Creo que hay una manera de hacer esto en este momento. Parece que la información se está compilando para

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator

en archivos como

UIKit.apinotesc UIKit.swiftdoc UIKit.swiftmodule

Las clases de *.swiftmodule son generadas por Xcode como parte de la compilación swift pero la información adicional puede estar en el archivo .apinotesc , que no parece haber una forma documentada de generarla en este momento.

Sin embargo, el comando swift tiene una opción -apinotes , que se utiliza para generar esto. Puede ver en /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc que puede analizar esto con:

xcrun swift -apinotes -binary-to-yaml -o=- /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc

Esto genera un archivo YAML que se parece a:

Classes: - Name: NSFileProviderExtension Availability: available AvailabilityMsg: '''' Methods: - Selector: ''URLForItemWithPersistentIdentifier:'' MethodKind: Instance Nullability: [ N ] NullabilityOfRet: U Availability: available AvailabilityMsg: ''''

Si fuera un apostador (y no lo soy), diría que MethodKind determina si se trata de una Instance o una Class y que Swift está utilizando la capacidad de nulidad para determinar si es opcional o no. Yo sospecharia

  • U - (implícitamente) sin envoltura opcional
  • O - opcional
  • N - no opcional?

Estas son suposiciones salvajes sin embargo.