¿Cómo puedo importar el código Swift a Objective-C?

281

Escribí una biblioteca en Swift y no pude importarla a mi proyecto actual, escrito en Objective-C.

¿Hay alguna forma de importarlo?

#import "SCLAlertView.swift" - 'SCLAlertView.swift' file not found
Viktor Radchenko
fuente
9
Me encanta este proyecto!
SleepsOnNewspapers

Respuestas:

430

Necesitas importar TargetName-Swift.h. Tenga en cuenta que es el nombre del objetivo: las otras respuestas cometen el error de usar el nombre de la clase.

Este archivo único es un encabezado autogenerado que define las interfaces Objective-C para todas las clases de Swift en su proyecto que se anotan @objco heredan de NSObject.

Consideraciones:

  • Si su nombre de destino contiene espacios, reemplácelos con guiones bajos (por ejemplo, se My Projectconvierte en My_Project-Swift.h)

  • Si su objetivo es un marco, debe importar <TargetName/TargetName-Swift.h>

  • Asegúrese de que su archivo Swift sea miembro del objetivo

Cuenta
fuente
55
Tenga en cuenta que si intenta utilizar el nombre de archivo Swift en su importación, obtendrá el error "Esperado ';' después del declarador de nivel superior ". en su archivo Swift después de "import Foundation".
louielouie
8
EDITAR: Nota: para que esto funcione, se DEBE definir un nombre de módulo de proyecto. Ver: stackoverflow.com/a/24064015/2085743
Ruben Martinez Jr.
77
Solo me gustaría agregar una nota de que si el nombre de su proyecto tiene algún espacio en blanco o carácter especial, debe reemplazarlos con guiones bajos, como "Mi aplicación" sería "My_App-Swift.h"
Hola Soy Edu Feliz Navidad
84
¿Por qué es esto tan difícil y mal documentado?
uchuugaka 01 de
3
@lelelo No, ese archivo es lo opuesto a este. El encabezado de puente está escrito por el desarrollador y le permite incorporar símbolos Objective-C y C en su código Swift. El archivo Target-Swift.h se genera automáticamente y permite que su código Objective-C / C acceda a los símbolos Swift.
Bill
154

Instrucciones del sitio web de Apple:

Para importar código Swift en Objective-C desde el mismo marco

En Configuración de compilación , en Empaquetado , asegúrese de que la configuración de Definir módulo para ese objetivo de marco esté establecida en . Importe el código Swift de ese objetivo de marco en cualquier archivo Objective-C .m dentro de ese objetivo de marco utilizando esta sintaxis y sustituyendo los nombres apropiados:

#import "ProductName-Swift.h"

Revisión:

Solo puede importar "ProductName-Swift.h" en archivos .m.

Los archivos Swift en su destino serán visibles en los archivos Objective-C .m que contienen esta declaración de importación.

Para evitar referencias cíclicas, no importe Swift en un archivo de encabezado Objective-C. En cambio, puede declarar hacia adelante una clase Swift para usarla en un encabezado Objective-C. Tenga en cuenta que no puede subclasificar una clase Swift en Objective-C.

ingrese la descripción de la imagen aquí

Andrei Papancea
fuente
2
Solo importar "ProductName-Swift.h" en archivos .m me ayudó. Agregar lo mismo en el archivo .pch daba "No se puede encontrar la declaración de protocolo para 'CLLocationManagerDelegate'; ¿quiso decir 'NSLayoutManagerDelegate'?"
Alphonse R. Dsouza
@AJit no lo hace directamente, la documentación lo dice. La forma más fácil es crear una clase Objective-C que se traduzca en un formato que Objective-C ++ entienda. developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Alejandro Iván
1
Tenga en cuenta que tiene que derivar de NSObject!!! no puedes simplemente declarar un class Blah en rápido y hacer que funcione. necesita serclass Blah : NSObject
David T.
Vale la pena leer esta respuesta para algunos casos: stackoverflow.com/questions/26328034/… Dependiendo de lo que esté haciendo: #import <ProductName / ProductModuleName-Swift.h> #import <ProductModuleName-Swift.h> #import <NewTestApp / NewTestApp -Swift.h>
inigo333
¿Qué sucede si desea importar una extensión Swift?
Ricardo
150

Esto es lo que debes hacer:

  1. Crear un nuevo proyecto en Objective-C

  2. Crea un nuevo .swiftarchivo  

    • Aparecerá una ventana emergente y preguntará "¿Desea configurar un encabezado de puente de Objective-C" ?
    • Elija .
  3. Haga clic en su archivo de proyecto Xcode

  4. Haga clic en Configuración de compilación

  5. Busque la barra de búsqueda y busque el módulo Define .

  6. Cambie el valor a .

  7. Buscar nombre del módulo del producto .

  8. Cambie el valor al nombre de su proyecto.

  9. En la aplicación delegada, agregue lo siguiente: #import "YourProjectName-Swift.h"


Nota: Siempre que quiera usar su archivo Swift, debe importar la siguiente línea:

#import "YourProjectName-Swift.h"

Sumit singh
fuente
1
Cambiar el valor de Defines moduleen Build settingsque Yeses lo que fija cosas para mí!
Zakaria Braksa
El contenido incrustado contiene Swift: SÍ UTILICE esto también
Mohit
44
buena respuesta, pero los pasos 7-8 no son necesarios en Xcode 7.3.1 y superior
Sam B
¡Trabajó para mi! Gracias.
itsdamslife
1
Sólo quiero añadir que YourProjectNameen #import "YourProjectName-Swift.h"será el nombre del proyecto a partir del paso 8. Es útil si el nombre del proyecto contiene caracteres especiales y no está seguro de qué es exactamente lo que debe formatearlo.
Chuck Boris el
40

Si está usando Cocoapods y está tratando de usar un pod Swift en un proyecto ObjC, simplemente puede hacer lo siguiente:

@import <FrameworkName>;

ingrese la descripción de la imagen aquí

KingPolygon
fuente
1
¡Muchas gracias! Salvaste mi día.
Esha
Esto funciona de maravilla si instalamos una biblioteca rápida a través de Cocoapods. ¡Votado!
NSPratik
21

Vaya a la configuración de compilación en su archivo de proyecto y busque "Nombre de encabezado de interfaz generado por Objective-C . El valor de esa propiedad es el nombre que debe incluir.

Si su propiedad "Nombre del módulo del producto" (de la que depende la propiedad anterior de forma predeterminada) varía en función de si compila para prueba / depuración / lanzamiento / etc. (como lo hace en mi caso), haga que esta propiedad sea independiente de eso variación estableciendo un nombre personalizado.

Lukas Kalinski
fuente
15

Importar el Swiftarchivo dentro Objective-cpuede causar este error, si no lo hace importcorrectamente.

NOTA: No tiene que importar archivos Swift externamente, solo tiene que importar un archivo que se encargue de los archivos Swift.

Cuando creó / copió el archivo Swift dentro del proyecto Objective-C . Hubiera creado un encabezado puente automáticamente.

Comprobar Objective-C Generated Interface Header Nameen Targets -> Build Settings.

ingrese la descripción de la imagen aquí

Según lo anterior, importaré KJExpandable-Swift.htal como está.

El suyo será TargetName-Swift.h, donde TargetNamedifiere según el nombre de su proyecto u otro objetivo que podría haber agregado y ejecutado en él.

Como debajo de mi objetivo es KJExpandable, entonces esKJExpandable-Swift.h
ingrese la descripción de la imagen aquí

Kiran Jasvanee
fuente
12

Primer paso:-

Seleccione Objetivo del proyecto -> Configuración de compilación -> Buscar ('Definir') -> Definir valor de actualización del módulo No a

"Define Módulo": .

"Incrustar siempre bibliotecas estándar de Swift": .

"Instalar el encabezado de compatibilidad de Objective-C": .

ingrese la descripción de la imagen aquí

Segundo paso:-

Agregue la clase de archivo Swift en el archivo Objective C ".h" como se muestra a continuación

#import <UIKit/UIKit.h>

@class TestViewController(Swift File);

@interface TestViewController(Objective C File) : UIViewController

@end

Importe 'ProjectName (Su nombre de proyecto) -Swift.h' en el archivo Objective C ".m"

//TestViewController.m 
#import "TestViewController.h"

/*import ProjectName-Swift.h file to access Swift file here*/

#import "ProjectName-Swift.h"
Darshan Panchal
fuente
¡La declaración de avance (@class) de la clase es un muy buen punto! ¡Gracias!
Philipp Otto
10

Hay una advertencia si está importando código Swift en sus archivos Objective-C dentro del mismo marco. Debe hacerlo especificando el nombre del marco y los corchetes angulares:

#import <MyFramework/MyFramework-Swift.h>

MyFrameworkaquí está la configuración de compilación "Nombre del módulo del producto" ( PRODUCT_NAME = MyFramework).

Simplemente agregar #import "MyFramework-Swift.h"no funcionará. Si verifica el directorio de productos compilados (antes de que #importse agregue, por lo que ha tenido al menos una compilación exitosa con algún código Swift en el destino), aún debería ver el archivo MyFramework-Swift.hen el Headersdirectorio.

Misha Karpenko
fuente
8

Si tiene un proyecto creado en Swift 4 y luego agregó archivos Objective-C, hágalo así:

@objcMembers
public class MyModel: NSObject {
    var someFlag = false         
    func doSomething() {         
        print("doing something")
    }
}

Referencia: https://useyourloaf.com/blog/objc-warnings-upgrading-to-swift-4/

Prashant Bhayani
fuente
En mi código, después de actualizarlo a Swift 4.2 desde swift 3. No funciona
SNarula
¿Qué error estás recibiendo? He usado el código anterior en Swift4.2 y funciona bien.
Prashant Bhayani
OK eso es genial.
Prashant Bhayani
4

Consulte las notas preliminares sobre Swift y Objective C en el mismo proyecto

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_75

Deberías estar importando

#import "SCLAlertView-Swift.h"
Nitin Alabur
fuente
3
Me mostró este error: no se encontró el archivo 'SCLAlertView-Swift.h'.
Viktor Radchenko
2
Debe ser el nombre del proyecto, no el nombre del archivo; vea mi respuesta.
Bill
1
Gracias por el enlace de documentación. Eso fue útil como referencia.
louielouie
2
Para citar desde el enlace provisto: The name of this header is your product module name followed by adding "-Swift.h".Entonces, no es el nombre de la clase como escribió, sino el nombre de su módulo de producto y eso se encarga de importar todos los archivos rápidos, no solo uno específico
Chris
4

Busque "Nombre del encabezado de la interfaz generada por Objective-C" en la Configuración de compilación del destino que está tratando de compilar (digamos que es MyApp-Swift.h) e importe el valor de esta configuración ( #import "MyApp-Swift.h") en el archivo de origen al que está intentando acceder sus API Swift

El valor predeterminado para este campo es $(SWIFT_MODULE_NAME)-Swift.h . Puede verlo si hace doble clic en el campo de valor de la configuración "Nombre del encabezado de la interfaz generada por Objective-C".

Además, si tiene guiones en el nombre de su módulo (digamos que es My-App), entonces $(SWIFT_MODULE_NAME)todos los guiones serán reemplazados por guiones bajos. Entonces tendrás que agregar #import "My_App-Swift.h".

Misha Karpenko
fuente
Mejor que el aprobado. Los guiones desperdiciaron 20 minutos Nunca volveré jaja.
Roi Mulia
3

Si desea utilizar el archivo Swift en la clase Objective-C , entonces, desde Xcode 8 en adelante, puede seguir los siguientes pasos:

Si ha creado el proyecto en Objective-C:

  1. Crear nuevo archivo Swift
  2. Xcode solicitará automáticamente el archivo Bridge-Header
  3. Generarlo
  4. Importe "ProjectName-Swift.h" en su controlador Objective-C (importe en la implementación no en la interfaz) (si su proyecto tiene espacio entre los nombres, utilice el guión bajo "Project_Name-Swift.h")
  5. Podrás acceder a tu clase de Objective-C en Swift.

Compílelo y si generará un error de enlazador como: compilado con una versión más nueva del lenguaje Swift (3.0) que los archivos anteriores (2.0) para arquitectura x86_64 o armv 7

Haz un cambio más en tu

  1. Xcode -> Proyecto -> Destino -> Configuración de compilación -> Usar versión de lenguaje heredado Swift -> Sí

Construye y corre.

Dheeraj D
fuente
1
No
obtengo
1

Tenga cuidado con los guiones y guiones bajos, pueden mezclarse y su Nombre de proyecto y Nombre de destino no serán los mismos que SWIFT_MODULE_NAME.

Guiones y guiones bajos

Naloiko Eugene
fuente
1
#import <TargetName-Swift.h>

verá cuando ingresa desde el teclado #import <y luego, automáticamente, Xcode le aconsejará.

Erhan Demirci
fuente
-1

Encuentra el archivo .PCH dentro del proyecto. y luego agregue #import "YourProjectName-Swift.h"Esto importará los encabezados de clase. Para que no tenga que importar a un archivo específico.

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif


#ifdef __OBJC__
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #import "YourProjectName-Swift.h"
#endif
Ram G.
fuente