objective entre diferencias ios objective-c swift

entre - swift ios



No puedo usar clases de Swift dentro de Objective-C (21)

Intento integrar el código Swift en mi aplicación. Mi aplicación está escrita en Objective-C y agregué una clase Swift . He hecho todo lo descrito here . Pero mi problema es que Xcode no ha creado el archivo -Swift.h , solo los encabezados de puente. Así que lo creé, pero en realidad está vacío. Puedo usar todas mis clases de ObjC en Swift, pero no puedo hacerlo al revés. @objc mi clase rápida con @objc pero no ayudó. ¿Qué puedo hacer ahora?

EDIT: Apple dice: "Cuando importa código Swift en Objective-C, confía en un archivo de encabezado Xcode-generated para exponer esos archivos a Objective-C. El nombre de este encabezado es el nombre del módulo del producto seguido añadiendo "-Swift.h". "

Ahora cuando quiero importar ese archivo, da un error:

//MainMenu.m #import "myProjectModule-Swift.h" //Error: ''myProjectModule-Swift.h'' file not found @implementation MainMenu

Aquí está mi archivo FBManager.swift:

@objc class FBManager: NSObject { var descr = "FBManager class" init() { super.init() } func desc(){ println(descr) } func getSharedGameState() -> GameState{ return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here } }


Acabo de descubrir que agregar un directorio de archivos swift a un proyecto no funcionará. Primero debe crear un grupo para el directorio, luego agregar los archivos swift ...


Asegúrese de que su proyecto define un módulo y le ha dado un nombre al módulo. Luego reconstruya, y Xcode creará el archivo de encabezado -Swift.h y podrá importar.

Puede establecer la definición del módulo y el nombre del módulo en la configuración de su proyecto.


Bueno, después de leer todos los comentarios y probar y leer e intentar nuevamente, logré incluir clases rápidas en mi proyecto Big obj-c. Así que, gracias por toda la ayuda. Quería compartir un consejo que me ayudó a entender mejor el proceso. En la clase .m, fui a la línea de importación del nombre de destino de Swift #import "myTargetName-Swift.h" y presioné la tecla:

comando + clic del ratón -> Saltar a definición

Allí puede ver todas las traducciones de swift a obj-c y, además, encontrará las diversas funciones re-declaradas en obj-c. Espero que este consejo te ayude tanto como a mí.


Después de hacer todo lo anterior, todavía tengo errores. Mi problema terminó siendo que los archivos Swift que necesitaba no se agregaron a los recursos del paquete por algún motivo.

Arreglé esto yendo a [MyTarget]> Build Phases> Copy Bundle Resources, luego hice clic en el botón más y agregué los archivos Swift.


El archivo se crea automáticamente (hablando de Xcode 6.3.2 aquí). Pero no lo verá, ya que está en su carpeta de Datos Derivados. Después de marcar su clase de swift con @objc , compile, luego busque Swift.h en su carpeta de Datos Derivados. Debes encontrar el encabezado Swift allí.

Tuve el problema, que Xcode cambió el nombre de my my-Project-Swift.h a my_Project-Swift.h Xcode no le gusta "." "-" "." "-" etc. símbolos. Con el método anterior, puede encontrar el nombre de archivo e importarlo a una clase de Objective-C.


En mi caso, aparte de estos pasos:

  1. Nombre del módulo del producto: myproject
  2. Define el módulo: sí
  3. El contenido incrustado contiene Swift: SI
  4. Instale el encabezado de compatibilidad de Objective-C: SI
  5. Objective-C Bridging Header: $ (SRCROOT) /Sources/SwiftBridging.h

He necesitado poner la clase como pública para crear el archivo productName-Swift.h :

import UIKit @objc public class TestSwift: NSObject { func sayHello() { print("Hi there!") } }


La respuesta de @sig es una de las mejores, sin embargo, no me funcionó con el proyecto anterior (¡no es nuevo!), necesitaba algunas modificaciones. Después de muchas variaciones encontré la receta para mí (usando XCode 7.2):

  1. Nombre del módulo del producto: $ (PRODUCT_NAME: c99extidentifier)
  2. Define el módulo: NO
  3. El contenido incrustado contiene Swift: NO
  4. Instale el encabezado de compatibilidad de Objective-C: SI
  5. Objective-C Bridging Header: ProjectName-Bridging-Header.h

El último punto (5) fue crucial. Lo puse solo en la segunda sección (campo Objetivos), el campo Proyecto debería dejarse vacío: De lo contrario, no generó el archivo "Project-Swift.h" correcto para mí (no incluyó métodos swift).


Mi problema fue que la generación automática del archivo -swift.h no pudo entender una subclase de CustomDebugStringConvertible. Cambié la clase para ser una subclase de NSObject en su lugar. Después de eso, el archivo -swift.h ahora incluía la clase correctamente.


No cree el archivo de encabezado usted mismo. Elimina el que creaste.

Asegúrese de que sus clases Swift estén etiquetadas con @objc o @objc de una clase que se derive (directa o indirectamente) de NSObject .

Xcode no generará el archivo si tiene algún error de compilación en su proyecto; asegúrese de que su proyecto se compile de forma limpia.


No tuve que cambiar ninguna configuración en la compilación o agregar @obj a la clase.

Todo lo que tuve que hacer fue crear un encabezado de puente que se creó automáticamente cuando creé las clases Swift en el proyecto Objective-c. Y luego solo tuve que hacer

importe "Bedtime-Swift.h" <- dentro del archivo object-c que necesitaba usar ese archivo swift.


Pasé aproximadamente 4 horas intentando habilitar Swift en mi proyecto basado en Xcode Objective-C. Mi myproject-Swift.h " myproject-Swift.h " se creó con éxito, pero mi Xcode no vio mis Swift-classes . Entonces, decidí crear un nuevo proyecto basado en Xcode Objc y, finalmente, ¡encontré la respuesta correcta! Espero que esta publicación ayude a alguien :-)

Paso a paso la integración de Swift para un proyecto basado en Xcode Objc:

  1. Cree un nuevo archivo *.swift (en Xcode) o agréguelo usando el Finder
  2. Cree un Objective-C bridging header cuando Xcode le pregunte sobre eso
  3. Implementa tu clase Swift:

    import Foundation // use @objc or @objcMembers annotation if necessary class Foo { //.. }

  4. Abre Configuración de compilación y verifica esos parámetros:

    • Define el módulo: sí

      Copiar y pegar el nombre del parámetro en una barra de búsqueda

    • Nombre del módulo del producto: myproject

      Asegúrese de que el Nombre del módulo de su producto no contenga ningún carácter especial

    • Instale el encabezado de compatibilidad de Objective-C: YES

      Una vez que haya agregado el archivo *.swift al proyecto, esta propiedad aparecerá en Configuración de compilación

    • Encabezado de interfaz generado por Objective-C: myproject-Swift.h

      Este encabezado es generado automáticamente por Xcode

    • Objective-C Bridging Header: $(SRCROOT)/myproject-Bridging-Header.h
  5. Importe el encabezado de la interfaz Swift en su archivo * .m

    #import "myproject-Swift.h"

    No preste atención a los errores y advertencias.

  6. Limpia y reconstruye tu proyecto Xcode
  7. ¡Lucro!

Permita que Xcode haga su trabajo, no agregue / cree el encabezado Swift manualmente. Solo agrega @objc antes de tu clase Swift ex.

@objc class YourSwiftClassName: UIViewController

En la configuración de su proyecto, busque las marcas de abajo y cámbiela a SÍ (Proyecto y Objetivo)

Defines Module : YES Always Embed Swift Standard Libraries : YES Install Objective-C Compatibility Header : YES

Luego limpie el proyecto y compile una vez, después de que la compilación sea exitosa (probablemente debería) importar debajo del archivo de encabezado en su clase de objetivo-c.

#import "YourProjectName-Swift.h"

¡Boooom!


Simplemente incluya #import "myProject-Swift.h" en el archivo .m o .h

PS No encontrará "myProject-Swift.h" en el inspector de archivos que está oculto. Pero es generado automáticamente por la aplicación.


También es probable que sea útil para aquellos de ustedes con un objetivo de Framework :

La declaración de importación del archivo de encabezado generado automáticamente se ve un poco diferente de los destinos de la aplicación. Además de las otras cosas mencionadas en otras respuestas use

#import <ProductName/ProductModuleName-Swift.h>

en lugar de

#import "ProductModuleName-Swift.h"

Según la documentación de Apple en Mix & Match para los objetivos del marco.


Tengo el mismo error: el archivo myProjectModule-Swift.h no se encontró ", pero, en mi caso, la razón real estaba en el destino de implementación incorrecto:" Swift no está disponible en OS X anterior a 10.9; establezca MACOSX_DEPLOYMENT_TARGET en 10.9 o posterior (actualmente es ''10 .7 '') "así que, cuando cambié el destino de implementación a 10.9, el proyecto se compiló correctamente.


Tuve el mismo problema y finalmente pareció que no estaban atados a los mismos objetivos. La clase ObjC se adjunta a Target1 y Target2, la clase Swift solo se adjunta a Target1 y no es visible dentro de la clase ObjC.

Espero que esto ayude a alguien.


Tuve el mismo problema y resultó que los símbolos especiales en el nombre del módulo se reemplazaron por xcode (en mi caso, los guiones terminaron siendo guiones bajos). En la configuración del proyecto, marque "nombre del módulo" para encontrar el nombre del módulo para su proyecto. Después de eso, use ModuleName-Swift.h o cambie el nombre del módulo en la configuración.


Tuve problemas en cuanto a que agregaría clases a mi encabezado puente objetivo-c, y en esos encabezados objetivo-c que se importaron, estaban tratando de importar el encabezado rápido. No le gustó eso.

Por lo tanto, en todas mis clases de objetivo-c que usan swift, pero también están puenteadas, la clave fue asegurarse de que usa declaraciones de clase hacia adelante en los encabezados, luego importe el archivo "* -Swift.h" en el archivo .m.


mi problema fue que me quedé atascado después de que xcode creara el archivo puente, pero aún así recibí un error en el nombre del archivo del encabezado MYPROJECTNAME-swift.h

1. Reviso el terminal y busco todos los archivos de puentes swift creados automáticamente:

find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -

ves lo que creó xcode.

  1. en mi caso, tenía espacio en el nombre de mi proyecto y reemplazar xcode es ''_''

Detalles: Proyecto Objective-C con código Swift 3 en Xcode 8.1

Tareas:

  1. Usar enumeración rápida en la clase de objetivos c
  2. Usa enumeración object-c en la clase swift

MUESTRA COMPLETA

1. Clase de Objective-C que utiliza enumeración Swift

ObjcClass.h

#import <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, ObjcEnum) { ObjcEnumValue1, ObjcEnumValue2, ObjcEnumValue3 }; @interface ObjcClass : NSObject + (void) PrintEnumValues; @end

ObjcClass.m

#import "ObjcClass.h" #import "SwiftCode.h" @implementation ObjcClass + (void) PrintEnumValues { [self PrintEnumValue:SwiftEnumValue1]; [self PrintEnumValue:SwiftEnumValue2]; [self PrintEnumValue:SwiftEnumValue3]; } + (void) PrintEnumValue:(SwiftEnum) value { switch (value) { case SwiftEnumValue1: NSLog(@"-- SwiftEnum: SwiftEnumValue1"); break; case SwiftEnumValue2: case SwiftEnumValue3: NSLog(@"-- SwiftEnum: long value = %ld", (long)value); break; } } @end

Detectar código Swift en código Objective-C

En mi muestra, uso SwiftCode.h para detectar el código Swift en Objective-C. Este archivo se genera automáticamente (no creé una copia física de este archivo de encabezado en un proyecto), y solo puede establecer el nombre de este archivo:

Si el compilador no puede encontrar el código Swift del archivo de encabezado, intente compilar el proyecto.

2. Clase Swift que utiliza enumeración Objective-C

import Foundation @objc enum SwiftEnum: Int { case Value1, Value2, Value3 } @objc class SwiftClass: NSObject { class func PrintEnumValues() { PrintEnumValue(.Value1) PrintEnumValue(.Value2) PrintEnumValue(.Value3) } class func PrintEnumValue(value: ObjcEnum) { switch value { case .Value1, .Value2: NSLog("-- ObjcEnum: int value = /(value.rawValue)") case .Value3: NSLog("-- ObjcEnum: Value3") break } } }

Detectar código Objective-C en código Swift

Es necesario crear un archivo de encabezado de puente. Cuando agregue el archivo Swift en el proyecto Objective-C, o el archivo Objective-C en el proyecto Swift, Xcode le sugerirá que cree un encabezado puente.

Puede cambiar el nombre del archivo de cabecera de puente aquí:

Bridging-Header.h

#import "ObjcClass.h"

Uso

#import "SwiftCode.h" ... [ObjcClass PrintEnumValues]; [SwiftClass PrintEnumValues]; [SwiftClass PrintEnumValue:ObjcEnumValue3];

Resultado

Mas muestras

Pasos completos de integración Objective-c y Swift descritos anteriormente . Ahora escribiré algunos otros ejemplos de código.

3. Llamar a la clase Swift desde el código de Objective-c

Clase rapida

import Foundation @objc class SwiftClass:NSObject { private var _stringValue: String var stringValue: String { get { print("SwiftClass get stringValue") return _stringValue } set { print("SwiftClass set stringValue = /(newValue)") _stringValue = newValue } } init (stringValue: String) { print("SwiftClass init(String)") _stringValue = stringValue } func printValue() { print("SwiftClass printValue()") print("stringValue = /(_stringValue)") } }

Código Objective-C (código de llamada)

SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"]; [obj printValue]; NSString * str = obj.stringValue; obj.stringValue = @"HeLLo wOrLd!!!";

Resultado

4. Llamar a la clase Objective-c desde el código Swift.

Clase de Objective-C (ObjcClass.h)

#import <Foundation/Foundation.h> @interface ObjcClass : NSObject @property NSString* stringValue; - (instancetype) initWithStringValue:(NSString*)stringValue; - (void) printValue; @end

ObjcClass.m

#import "ObjcClass.h" @interface ObjcClass() @property NSString* strValue; @end @implementation ObjcClass - (instancetype) initWithStringValue:(NSString*)stringValue { NSLog(@"ObjcClass initWithStringValue"); _strValue = stringValue; return self; } - (void) printValue { NSLog(@"ObjcClass printValue"); NSLog(@"stringValue = %@", _strValue); } - (NSString*) stringValue { NSLog(@"ObjcClass get stringValue"); return _strValue; } - (void) setStringValue:(NSString*)newValue { NSLog(@"ObjcClass set stringValue = %@", newValue); _strValue = newValue; } @end

Código Swift (código de llamada)

if let obj = ObjcClass(stringValue: "Hello World!") { obj.printValue() let str = obj.stringValue; obj.stringValue = "HeLLo wOrLd!!!"; }

Resultado

5. Usa la extensión Swift en el código de Objective-c

Extensión rápida

extension UIView { static func swiftExtensionFunc() { NSLog("UIView swiftExtensionFunc") } }

Código Objective-C (código de llamada)

[UIView swiftExtensionFunc];

6. Usa la extensión Objective-c en el código swift

Extensión de Objective-C (UIViewExtension.h)

#import <UIKit/UIKit.h> @interface UIView (ObjcAdditions) + (void)objcExtensionFunc; @end

UIViewExtension.m

@implementation UIView (ObjcAdditions) + (void)objcExtensionFunc { NSLog(@"UIView objcExtensionFunc"); } @end

Código Swift (código de llamada)

UIView.objcExtensionFunc()


Hay dos condiciones,

  • Usa tu archivo swift en el archivo de objetivos c.
  • Usa tu archivo objetivo c en el archivo swift.

Entonces, para ese propósito, tienes que seguir estos pasos:

  • Agregue su archivo swift en un proyecto objetivo-c o viceversa.
  • Crear un archivo de encabezado (.h).
  • Vaya a Crear configuración y realice los siguientes pasos con la búsqueda,

    1. busque este texto "brid" y establezca una ruta de acceso de su archivo de encabezado.
    2. "Define Module": YES.
    3. "Siempre incrustar bibliotecas estándar de Swift": SÍ.
    4. "Instalar el encabezado de compatibilidad de Objective-C": SI.

Después de eso, limpia y reconstruye tu proyecto.

Usa tu archivo swift en el archivo de objetivos c.

En ese caso, primero escribe "@objc" antes de tu clase en el archivo swift.

Después de eso, en tu archivo objetivo c, escribe esto,

#import "YourProjectName-Swift.h"

Usa tu archivo objetivo c en el archivo swift.

En ese caso, en su archivo de cabecera, escriba esto,

#import "YourObjective-c_FileName.h"

Espero que esto ayude.