¿Cómo llamo al código Objective-C desde Swift?

Resuelto David Mulder asked hace 10 años • 17 respuestas

En Swift, ¿cómo se llama al código Objective-C?

Apple mencionó que podrían coexistir en una aplicación, pero ¿significa esto que técnicamente se podrían reutilizar clases antiguas creadas en Objective-C mientras se crean nuevas clases en Swift?

David Mulder avatar Jun 03 '14 03:06 David Mulder
Aceptado

Usando clases Objective-C en Swift

Si tiene una clase existente que le gustaría usar, realice el Paso 2 y luego salte al Paso 5 . (En algunos casos, tuve que agregar un archivo explícito #import <Foundation/Foundation.ha un archivo Objective-C anterior).

Paso 1: Agregar la implementación de Objective-C - .m

Agregue un .marchivo a su clase y asígnele el nombre CustomObject.m.

Paso 2: agregar encabezado de puente

Al agregar su .marchivo, probablemente recibirá un mensaje similar a este:

Un cuadro de diálogo estilo hoja de macOS de Xcode que le pregunta si "le gustaría configurar un encabezado puente Objective-C"

Haga clic en ¡ !

Si no vio el mensaje o eliminó accidentalmente su encabezado puente, agregue un nuevo .harchivo a su proyecto y asígnele el nombre <#YourProjectName#>-Bridging-Header.h.

En algunas situaciones, particularmente cuando se trabaja con marcos Objective-C, no agrega una clase Objective-C explícitamente y Xcode no puede encontrar el vinculador. En este caso, cree su .harchivo con el nombre mencionado anteriormente, luego asegúrese de vincular su ruta en la configuración del proyecto de su destino de esta manera:

Una animación que demuestra el párrafo anterior.

Nota:

Es una buena práctica vincular su proyecto usando la $(SRCROOT)macro para que, si mueve su proyecto o trabaja en él con otras personas usando un repositorio remoto, siga funcionando. $(SRCROOT)Puede considerarse como el directorio que contiene su archivo .xcodeproj. Podría verse así:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Paso 3: Agregar encabezado Objective-C - .h

Agregue otro .harchivo y asígnele un nombre CustomObject.h.

Paso 4: construye tu clase Objective-C

EnCustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

EnCustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

Paso 5: agregar clase al encabezado puente

En YourProject-Bridging-Header.h:

#import "CustomObject.h"

Paso 6: usa tu objeto

En SomeSwiftFile.swift:

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

No es necesario importar explícitamente; para eso está el encabezado puente.

Usando clases Swift en Objective-C

Paso 1: crear una nueva clase Swift

Agregue un .swiftarchivo a su proyecto y asígnele el nombre MySwiftObject.swift.

En MySwiftObject.swift:

import Foundation

@objc(MySwiftObject)
class MySwiftObject : NSObject {

    @objc
    var someProperty: AnyObject = "Some Initializer Val" as NSString

    init() {}

    @objc
    func someFunction(someArg: Any) -> NSString {
        return "You sent me \(someArg)"
    }
}

Paso 2: importar archivos Swift a la clase ObjC

En SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

El archivo: <#YourProjectName#>-Swift.hya debería estar creado automáticamente en tu proyecto, incluso si no puedes verlo.

Paso 3: Usa tu clase

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];

NSLog(@"RetString: %@", retString);

Notas:

  1. Si la finalización de código no se comporta como esperaba, intente ejecutar una compilación rápida Rpara ayudar a Xcode a encontrar parte del código Objective-C en un contexto Swift y viceversa.

  2. Si agrega un .swiftarchivo a un proyecto anterior y obtiene el error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, intente reiniciar Xcode por completo .

  3. Si bien originalmente era posible usar clases Swift puras (no descendientes de NSObject) que son visibles para Objective-C mediante el uso del @objcprefijo, esto ya no es posible. Ahora, para ser visible en Objective-C, el objeto Swift debe ser una clase conforme NSObjectProtocol(la forma más fácil de hacerlo es heredar de NSObject), o estar enummarcado @objccon un valor sin formato de algún tipo entero como Int. Puede ver el historial de ediciones para ver un ejemplo de código Swift 1.x @objcsin estas restricciones.

Logan avatar Jun 03 '2014 00:06 Logan

Consulte la guía de Apple para usar Swift con Cocoa y Objective-C . Esta guía cubre cómo usar código Objective-C y C de Swift y viceversa y tiene recomendaciones sobre cómo convertir un proyecto o mezclar y combinar partes de Objective-C/C y Swift en un proyecto existente.

El compilador genera automáticamente la sintaxis Swift para llamar a funciones C y métodos Objective-C. Como se ve en la documentación, este Objective-C:

UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

se convierte en este código Swift:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

Xcode también hace esta traducción sobre la marcha: puede usar Abrir rápidamente mientras edita un archivo Swift y escribir un nombre de clase Objective-C, y lo llevará a una versión Swift del encabezado de clase. (También puede obtener esto haciendo clic con cmd en un símbolo API en un archivo Swift). Y toda la documentación de referencia de API en las bibliotecas para desarrolladores de iOS 8 y OS X v10.10 (Yosemite) es visible tanto en Objective-C como en Swift. formas (por ejemplo UIView).

rickster avatar Jun 02 '2014 20:06 rickster

Aquí hay instrucciones paso a paso para usar código Objective-C (en este caso, un marco proporcionado por un tercero) en un proyecto Swift:

  1. Agregue cualquier archivo Objective-C a su proyecto Swift eligiendo Archivo -> Nuevo -> Nuevo archivo -> Archivo Objective-C. Al guardar, Xcode le preguntará si desea agregar un encabezado puente . Elija ' '. (fuente: derrrick.com )Gif: agregar un archivo vacío al proyecto y generar un encabezado puente

En sencillos pasos:

  1. Aparece un mensaje y luego haga clic en Aceptar... Si no aparece, lo creamos manualmente como se muestra a continuación... Cree un archivo de encabezado desde la fuente de iOS y asigne el nombre NombreProyecto-Bridging-Header (ejemplo: Prueba -Bridging-Header), y luego vaya a la configuración de compilación en el código del compilador Swift -> Puente Objective-C agregue el nombre del puente Objective-C... (Test/Test-Bridging-Header.h). Sí, eso está completo.

  2. Opcionalmente, elimine el archivo Objective-C que agregó (llamado "cualquier cosa" en la imagen GIF de arriba). Ya no lo necesitas.

  3. Abra el archivo de encabezado puente ; el nombre del archivo tiene el formato [SuProyecto]-Bridging-Header.h . Incluye un comentario proporcionado por Xcode. Agregue una línea de código para el archivo Objective-C que desea incluir , como un marco de trabajo de terceros. Por ejemplo, para agregar Mixpanel a su proyecto, deberá agregar la siguiente línea de código al archivo de encabezado puente:

    #importar "Mixpanel.h"
  4. Ahora, en cualquier archivo Swift, puede usar el código Objective-C existente, en la sintaxis Swift (en el caso de este ejemplo, puede llamar a los métodos del SDK de Mixpanel, etc.). Debe familiarizarse con cómo Xcode traduce Objective-C a Swift. La guía de Apple es de lectura rápida. O consulte esta respuesta para obtener un resumen incompleto.

Ejemplo de panel mixto:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Mixpanel.sharedInstanceWithToken("your-token")
    return true
}

¡Eso es todo!

Nota: Si elimina el archivo de encabezado puente de su proyecto , asegúrese de ir a Configuración de compilación y eliminar el valor de " Encabezado puente Objective-C " en "Compilador Swift - Generación de código".

derrrick avatar Feb 12 '2015 19:02 derrrick