En Swift, ¿cómo se llama el código Objective-C?
Apple mencionó que podrían coexistir en una aplicación, pero ¿significa esto que técnicamente se podrían reutilizar las clases antiguas hechas en Objective-C mientras se crean nuevas clases en Swift?
En Swift, ¿cómo se llama el código Objective-C?
Apple mencionó que podrían coexistir en una aplicación, pero ¿significa esto que técnicamente se podrían reutilizar las clases antiguas hechas en Objective-C mientras se crean nuevas clases en Swift?
Respuestas:
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
#import <Foundation/Foundation.h
archivo explícito a un archivo Objective-C anterior).
Agregue un .m
archivo a su clase y asígnele un nombre CustomObject.m
.
Al agregar su .m
archivo, es probable que reciba un mensaje similar al siguiente:
Haga clic en sí !
Si no vio el mensaje o borró accidentalmente su encabezado de puente, agregue un nuevo .h
archivo a su proyecto y asígnele un nombre <#YourProjectName#>-Bridging-Header.h
.
En algunas situaciones, particularmente cuando se trabaja con marcos Objective-C, no se agrega una clase Objective-C explícitamente y Xcode no puede encontrar el enlazador. En este caso, cree su .h
archivo nombrado como se mencionó anteriormente, luego asegúrese de vincular su ruta en la configuración del proyecto de destino de la siguiente manera:
Nota:
Es una buena práctica vincular su proyecto usando la $(SRCROOT)
macro para que si mueve su proyecto o trabaja con otros usando un repositorio remoto, todavía funcionará. $(SRCROOT)
puede considerarse como el directorio que contiene su archivo .xcodeproj. Podría verse así:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
Agregue otro .h
archivo y asígnele un nombre CustomObject.h
.
En CustomObject.h
#import <Foundation/Foundation.h>
@interface CustomObject : NSObject
@property (strong, nonatomic) id someProperty;
- (void) someMethod;
@end
En CustomObject.m
#import "CustomObject.h"
@implementation CustomObject
- (void) someMethod {
NSLog(@"SomeMethod Ran");
}
@end
En YourProject-Bridging-Header.h
:
#import "CustomObject.h"
En SomeSwiftFile.swift
:
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
No hay necesidad de importar explícitamente; para eso sirve el encabezado de puente.
Agregue un .swift
archivo a su proyecto y asígnele un 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)"
}
}
En SomeRandomClass.m
:
#import "<#YourProjectName#>-Swift.h"
El archivo: <#YourProjectName#>-Swift.h
ya debe crearse automáticamente en su proyecto, incluso si no puede verlo.
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);
Si la finalización del código no se comporta como espera, intente ejecutar una compilación rápida ⌘⇧Rpara ayudar a Xcode a encontrar parte del código de Objective-C en un contexto Swift y viceversa.
Si agrega un .swift
archivo a un proyecto anterior y obtiene el error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, intente reiniciar completamente Xcode .
Si bien originalmente era posible usar clases Swift puras (no descendientes de NSObject
) que son visibles para Objective-C usando el @objc
prefijo, 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 debe estar enum
marcado @objc
con un valor sin formato de algún tipo entero como Int
. Puede ver el historial de edición para un ejemplo de código Swift 1.x @objc
sin estas restricciones.
Consulte la guía de Apple para usar Swift con Cocoa y Objective-C . Esta guía cubre cómo usar el código Objective-C y C de Swift y viceversa y tiene recomendaciones sobre cómo convertir un proyecto o mezclar y combinar partes 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-ified del encabezado de clase. (También puede obtener esto haciendo clic en un símbolo API en un archivo Swift). Y toda la documentación de referencia API en las bibliotecas de desarrollador iOS 8 y OS X v10.10 (Yosemite) está visible tanto en Objective-C como en Swift formas (por ejemplo UIView
).
Aquí hay instrucciones paso a paso para usar el código Objective-C (en este caso, un marco proporcionado por un tercero) en un proyecto Swift:
En simples pasos:
Aparece un mensaje y luego haga clic en Aceptar ... Si no aparece, lo creamos manualmente como en el siguiente ... Cree un archivo de encabezado desde la fuente de iOS y déle el nombre ProjectName-Bridging-Header (ejemplo: Prueba -Bridging-Header), y luego vaya a la configuración de compilación en el código del compilador Swift -> Objective-C bridge agregue Objective-C bridge name .. (Test / Test-Bridging-Header.h). Sí, eso está completo.
Opcionalmente, elimine el archivo Objective-C que agregó (denominado "cualquier cosa" en la imagen GIF anterior). No lo necesitas más.
Abra el archivo de encabezado de puente : el nombre del archivo tiene la forma [YourProject] -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 terceros. Por ejemplo, para agregar Mixpanel a su proyecto, deberá agregar la siguiente línea de código al archivo de encabezado de puente:
#import "Mixpanel.h"
Ahora, en cualquier archivo Swift, puede usar el código Objective-C existente, en la sintaxis Swift (en el caso de este ejemplo, y puede llamar a los métodos del SDK de Mixpanel, etc.). Debe familiarizarse con la forma en que Xcode traduce Objective-C a Swift. La guía de Apple es una lectura rápida. O vea esta respuesta para un resumen incompleto.
Ejemplo para Mixpanel:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Mixpanel.sharedInstanceWithToken("your-token")
return true
}
¡Eso es!
Nota: Si elimina el archivo de encabezado de puente de su proyecto , asegúrese de ir a Configuración de compilación y elimine el valor de " Encabezado de puente de Objective-C " en "Compilador rápido - Generación de código".
Puedes leer la bonita publicación Swift & Cocoapods . Básicamente, necesitamos crear un archivo de encabezado de puente y colocar todos los encabezados de Objective-C allí. Y luego necesitamos hacer referencia a él desde nuestra configuración de compilación. Después de eso, podemos usar el código Objective-C.
let manager = AFHTTPRequestOperationManager()
manager.GET(
"http://example.com/resources.json",
parameters: nil,
success: { (operation: AFHTTPRequestOperation!,
responseObject: AnyObject!) in
println("JSON: " + responseObject.description)
},
failure: { (operation: AFHTTPRequestOperation!,
error: NSError!) in
println("Error: " + error.localizedDescription)
})
También eche un vistazo al documento de Apple Usando Swift con Cocoa y Objective-C también.
Escribí un proyecto simple de Xcode 6 que muestra cómo mezclar C ++, Objective-C y código Swift:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
En particular, el ejemplo llama a una función Objective-C y C ++ desde Swift .
La clave es crear un encabezado compartido, Project-Bridging-Header.h, y colocar los encabezados de Objective-C allí.
Descargue el proyecto como un ejemplo completo.
Estoy muy agradecido por la respuesta de @ Logan. Ayuda mucho crear un archivo puente y configuraciones.
Pero después de hacer todos estos pasos, todavía no obtengo una clase Objective-C en Swift.
Usé la cocoapods
biblioteca y la integré en mi proyecto. Lo cual es pod "pop"
.
Entonces, si está utilizando vainas de Objective-C en Swift, entonces puede haber una posibilidad de que no pueda acceder a import
las clases o Swift.
Lo simple que tienes que hacer es:
<YOUR-PROJECT>-Bridging-Header
archivo y#import <ObjC_Framework>
para@import ObjC_Framework
Por ejemplo: (biblioteca pop)
Reemplazar
#import <pop/POP.h>
con
@import pop;
Úselo clang import
cuando #import
no esté funcionando.
Cita de la documentación :
Cualquier marco Objective-C (o biblioteca C) que sea accesible como módulo puede importarse directamente a Swift. Esto incluye todos los marcos del sistema Objective-C, como Foundation, UIKit y SpriteKit, así como las bibliotecas C comunes que se proporcionan con el sistema. Por ejemplo, para importar Foundation, simplemente agregue esta declaración de importación en la parte superior del archivo Swift en el que está trabajando:
import Foundation
Esta importación hace que todas las API de Foundation, incluidas NSDate, NSURL, NSMutableData y todos sus métodos, propiedades y categorías, estén disponibles directamente en Swift.
Solo una nota para quien intente agregar una biblioteca Objective-C a Swift: debe agregar -ObjC en Configuración de compilación -> Vinculación -> Otras banderas de vinculador .
Después de crear un encabezado de puente, vaya a Configuración de compilación => Buscar "Encabezado de puente de Objective-C".
Justo debajo encontrará el archivo "" Nombre de encabezado de interfaz generado por Objective-C ".
Importe ese archivo en su controlador de vista.
Ejemplo: en mi caso: "Dauble-Swift.h"
Haga clic en el menú Nuevo archivo y elija el idioma de selección de archivos Objetivo. En ese momento, genera automáticamente un archivo "Encabezado de puente de Objective-C" que se utiliza para definir algún nombre de clase.
"Encabezado de puente Objective-C" en "Compilador rápido - Generación de código".
He agregado el proyecto en github que incluye una pequeña muestra para llamar rápidamente al código objetivo c.
En el proyecto Swift 4.2.1 en Xcode 10.1 puede agregar fácilmente el archivo Objective-C. Siga los pasos a continuación para conectar el archivo Objective-C al proyecto Swift.
Paso_01: Cree un nuevo proyecto Xcode usando el lenguaje Swift:
File
> New
> Project
> objc
.
Paso_02: en el proyecto Swift, agregue un nuevo archivo Objective-C:
File
> New
> File...
> macOS
> Objective-C File
.
Paso_03: si agrega un nuevo archivo Objective-C al proyecto Swift por primera vez, Xcode le pregunta:
Would you like to configure an Objective-C bridging header
?
Paso_04: selecciona la opción:
Create Bridging Header
.
Paso_05: se generará un archivo correspondiente con un nombre:
Objc-Bridging-Header.h
.
Paso_06: Ahora, necesita configurar la ruta del archivo Bridge en el encabezado del puente. En Project Navigator, haga clic en proyecto con nombre objc
y luego elija:
Build Settings
> Objective-C Bridging Header
> Objc-Bridging-Header.h
.
Paso_07: Arrastra y suelta tu Objc-Bridging-Header.h
en ese cuadro para generar una ruta de archivo.
Paso_08: Abra su Objc-Bridging-Header.h
archivo e importe el archivo Objective-C que desea usar en su archivo Swift.
#import "SpecialObjcFile.m"
Aquí hay un contenido de SpecialObjcFile.m
:
#import <Foundation/Foundation.h>
@interface Person: NSObject {
@public
bool busy;
}
@property
bool busy;
@end
Paso_09: ahora en su archivo Swift, puede usar una clase Objective-C:
override func viewDidLoad() {
super.viewDidLoad()
let myObjcContent = Person()
print(myObjcContent.busy)
}
La respuesta de Logans funciona bien, excepto que en la última Swift 5
da algún error de compilación. Aquí está la solución para las personas que trabajan en Swift 5.
import Foundation
class MySwiftObject : NSObject {
var someProperty: AnyObject = "Some Initializer Val" as AnyObject
override init() {}
func someFunction(someArg:AnyObject) -> String {
let returnVal = "You sent me \(someArg)"
return returnVal
}
}
Agregar un encabezado .h
y .m
archivos de implementación : archivo de clase Cocoa (Objective-C)
Por ejemploMyFileName
configurar el encabezado de puente
Cuando vea Would you like to configure an Objective-C bridging header
clic - Sí
<target_name>-Bridging-Header.h
se generará automáticamenteAgregar clase a Bridging-Header
En <target_name>-Bridging-Header.h
agregar una línea#import "<MyFileName>.h"
PD: si debe agregar archivos Objective-C existentes en el proyecto Swift, agregue de Bridging-Header.h
antemano
Agrega un <MyFileName>.swift
y extiendeNSObject
Importar archivos Swift a ObjC Class
Agregar #import "<#YourProjectName#>-Swift.h"
a su archivo Objective-C
Marcar el código público de Swift [@objc y @objcMembers]
Apple ha proporcionado una guía oficial en este documento: cómo-llamar-objetivo-c-código-de-rápido
Aquí está la parte relevante:
Para importar un conjunto de archivos Objective-C en el código Swift dentro del mismo objetivo de la aplicación, debe confiar en un archivo de encabezado de puente Objective-C para exponer esos archivos a Swift . Xcode ofrece crear este encabezado cuando agrega un archivo Swift a una aplicación Objective-C existente, o un archivo Objective-C a una aplicación Swift existente.
Si acepta, Xcode crea el archivo de encabezado de puente junto con el archivo que estaba creando y lo nombra usando el nombre del módulo del producto seguido de "-Bridging-Header.h". Alternativamente, puede crear un encabezado puente usted mismo seleccionando Archivo> Nuevo> Archivo> [sistema operativo]> Fuente> Archivo de encabezado
Edite el encabezado de puente para exponer su código Objective-C a su código Swift:
Swift puede ver todos los encabezados públicos de Objective-C que figuran en el encabezado de puente.
Enfoque de dos vías para usar el objetivo-c objetivo-c
1
2
Ahora bien para ir Gracias