Como posso importar o código Swift para o Objective-C?

281

Eu escrevi uma biblioteca no Swift e não pude importá-la para o meu projeto atual, escrito em Objective-C.

Existem maneiras de importá-lo?

#import "SCLAlertView.swift" - 'SCLAlertView.swift' file not found
Viktor Radchenko
fonte
9
amo este projeto!
SleepsOnNewspapers

Respostas:

430

Você precisa importar TargetName-Swift.h. Observe que é o nome do destino - as outras respostas cometem o erro de usar o nome da classe.

Esse arquivo único é um cabeçalho gerado automaticamente que define as interfaces Objective-C para todas as classes Swift no seu projeto que são anotadas @objcou herdadas de NSObject.

Considerações:

  • Se o nome do seu destino contiver espaços, substitua-os por sublinhados (por exemplo, My Projecttorna-se My_Project-Swift.h)

  • Se seu destino for uma estrutura, você precisará importar <TargetName/TargetName-Swift.h>

  • Verifique se o seu arquivo Swift é membro do destino

Conta
fonte
5
Observe que, se você tentar usar o nome do arquivo Swift em sua importação, receberá o erro "Expected ';' após o declarador de nível superior ". no seu arquivo Swift depois de "importar Foundation".
9789 Louiseouie
8
EDIT: Nota: para que isso funcione, um nome do módulo do projeto DEVE ser definido. Veja: stackoverflow.com/a/24064015/2085743
Ruben Martinez Jr.
7
Gostaria apenas de acrescentar que, se o nome do seu projeto tiver espaços em branco ou caracteres especiais, você deverá substituí-los por sublinhados, como "Meu aplicativo" seria "My_App-Swift.h"
Hola Soy Edu Feliz Navidad
84
Por que isso é tão difícil e mal documentado?
uchuugaka
3
@elelelo Não, esse arquivo é o oposto deste. O cabeçalho da ponte é escrito pelo desenvolvedor e permite que você traga símbolos Objective-C e C para o seu código Swift. O arquivo Target-Swift.h é gerado automaticamente e permite que seu código Objective-C / C acesse os símbolos Swift.
Bill
154

Instruções do site da Apple:

Para importar código Swift para o Objective-C da mesma estrutura

Em Configurações de compilação , em Empacotamento , verifique se a configuração Define Module para esse destino da estrutura está definida como Sim . Importe o código Swift desse destino da estrutura para qualquer arquivo Objective-C .m dentro desse destino da estrutura usando esta sintaxe e substituindo os nomes apropriados:

#import "ProductName-Swift.h"

Revisão:

Você pode importar apenas "ProductName-Swift.h" em arquivos .m.

Os arquivos Swift no seu destino estarão visíveis nos arquivos Objective-C .m que contêm esta declaração de importação.

Para evitar referências cíclicas, não importe o Swift para um arquivo de cabeçalho Objective-C. Em vez disso, você pode encaminhar declarar uma classe Swift para usá-la em um cabeçalho Objective-C. Observe que você não pode subclassificar uma classe Swift em Objective-C.

insira a descrição da imagem aqui

Andrei Papancea
fonte
2
Importar apenas "ProductName-Swift.h" em arquivos .m me ajudou. A adição do mesmo no arquivo .pch estava fornecendo "Não foi possível encontrar a declaração de protocolo para 'CLLocationManagerDelegate'; você quis dizer 'NSLayoutManagerDelegate'?"
Alphonse R. Dsouza
@AJit não é diretamente, a documentação diz isso. A maneira mais fácil é criar uma classe Objective-C que seja traduzida em um formato que o Objective-C ++ entenda. developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Alejandro Iván
1
Note que você deve derivar de NSObject!!! você não pode simplesmente declarar um class Blah rápido e fazê-lo funcionar. precisa serclass Blah : NSObject
David T.
Vale a pena ler esta resposta em alguns casos: stackoverflow.com/questions/26328034/… Dependendo do que você está fazendo: #import <ProductName / ProductModuleName-Swift.h> #import <ProductModuleName-Swift.h> #import <NewTestApp / NewTestApp -Swift.h>
inigo333
E se você quiser importar uma extensão Swift?
Ricardo
150

Aqui está o que fazer:

  1. Crie um novo projeto no Objective-C

  2. Crie um novo .swiftarquivo  

    • Uma janela pop-up será exibida e perguntará "Deseja configurar um cabeçalho de ponte Objective-C" .
    • Escolha Sim .
  3. Clique no seu arquivo Xcode Project

  4. Clique em Configurações de compilação

  5. Localize a barra de pesquisa e procure o módulo Defines .

  6. Altere o valor para Sim .

  7. Pesquisar nome do módulo do produto .

  8. Mude o valor para o nome do seu projeto.

  9. No delegado do aplicativo, adicione o seguinte: #import "YourProjectName-Swift.h"


Nota: Sempre que quiser usar seu arquivo Swift, você deve importar a seguinte linha:

#import "YourProjectName-Swift.h"

Sumit singh
fonte
1
Mudar o valor Defines moduleem Build settingsque Yesé o que fixa as coisas para mim!
Zakaria Braksa
Conteúdo incorporado contém Swift: USE YES isso também
Mohit
4
boa resposta, mas as etapas 7 a 8 não são necessárias no Xcode 7.3.1 e superior #
Sam B
Trabalhou para mim! Obrigado.
Itsdamslife 07/07
1
Só quero acrescentar que YourProjectNameem #import "YourProjectName-Swift.h"será o nome do projeto a partir do passo 8. útil se o nome do projeto contém caracteres especiais e você não tem certeza de como exatamente você deve formatá-lo.
Chuck Boris
40

Se você estiver usando Cocoapods e tentando usar um pod Swift em um projeto ObjC, basta fazer o seguinte:

@import <FrameworkName>;

insira a descrição da imagem aqui

KingPolygon
fonte
1
Muito obrigado! você salvou meu dia.
Esha
Isso funciona como um encanto se instalamos uma biblioteca rápida através do Cocoapods. Voto a favor !!!
NSPratik
21

Vá para criar configurações no arquivo do projeto e procure por "Nome do cabeçalho da interface gerada por Objective-C . O valor dessa propriedade é o nome que você deve incluir.

Se a propriedade "Nome do módulo do produto" (aquela da qual a propriedade acima depende por padrão) variar dependendo de você compilar para teste / depuração / release / etc (como no meu caso), torne essa propriedade independente disso variação, definindo um nome personalizado.

Lukas Kalinski
fonte
15

A importação do Swiftarquivo para dentro Objective-cpode causar esse erro, se não funcionar importcorretamente.

NOTA: Você não precisa importar arquivos Swift externamente, basta importar um arquivo que cuide de arquivos swift.

Quando você criou / copiou o arquivo Swift no projeto Objective-C . Teria criado um cabeçalho de ponte automaticamente.

Verifique Objective-C Generated Interface Header Nameem Targets -> Build Settings.

insira a descrição da imagem aqui

Com base no exposto, vou importar KJExpandable-Swift.hcomo está.

Seu será TargetName-Swift.h, Onde TargetNamedifere com base no nome do seu projeto ou em outro destino que você possa ter adicionado e executado nele.

Como abaixo do meu objetivo KJExpandable, éKJExpandable-Swift.h
insira a descrição da imagem aqui

Kiran Jasvanee
fonte
12

Primeiro passo:-

Selecione Alvo do projeto -> Configuração da compilação -> Pesquisa ('Definir') -> Definir valor de atualização do módulo Não para Sim

"Define Module": SIM .

"Sempre incorpore bibliotecas padrão do Swift": SIM .

"Instalar cabeçalho de compatibilidade do Objective-C": SIM .

insira a descrição da imagem aqui

Segundo passo:-

Adicionar classe de arquivo Swift no arquivo de objetivo C ".h", conforme abaixo

#import <UIKit/UIKit.h>

@class TestViewController(Swift File);

@interface TestViewController(Objective C File) : UIViewController

@end

Importar 'ProjectName (nome do seu projeto) -Swift.h' no arquivo Objective C ".m"

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

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

#import "ProjectName-Swift.h"
Darshan Panchal
fonte
A declaração de encaminhamento (@class) da classe é um ponto muito bom! Obrigado!
Philipp Otto
10

Há uma ressalva se você estiver importando o código Swift para seus arquivos Objective-C dentro da mesma estrutura. Você precisa fazer isso especificando o nome da estrutura e os colchetes angulares:

#import <MyFramework/MyFramework-Swift.h>

MyFrameworkaqui está a configuração de compilação "Nome do módulo do produto" ( PRODUCT_NAME = MyFramework).

Simplesmente adicionar #import "MyFramework-Swift.h"não funcionará. Se você verificar o diretório de produtos criados (antes de #importadicionar um desses , para ter pelo menos uma compilação bem-sucedida com algum código Swift no destino), ainda deverá ver o arquivo MyFramework-Swift.hno Headersdiretório

Misha Karpenko
fonte
8

Se você tem um projeto criado no Swift 4 e adicionou arquivos Objective-C, faça o seguinte:

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

Referência: https://useyourloaf.com/blog/objc-warnings-upgrading-to-swift-4/

Prashant Bhayani
fonte
No meu código, depois que eu atualizei para Swift 4.2 de rápida 3. Não está funcionando
SNarula
que erro você está tendo? Eu usei o código acima no Swift4.2 e está funcionando bem.
Prashant Bhayani 10/03/19
Ok, isso é ótimo.
Prashant Bhayani
4

Confira as notas de pré-lançamento sobre Swift e Objective C no mesmo projeto

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

Você deveria estar importando

#import "SCLAlertView-Swift.h"
Nitin Alabur
fonte
3
Me mostrou este erro: Arquivo 'SCLAlertView-Swift.h' não encontrado.
Viktor Radchenko
2
Precisa ser o nome do projeto, não o nome do arquivo - veja minha resposta.
Bill
1
Obrigado pelo link da documentação. Isso foi útil para referência.
9139 louielouie
2
Para citar o link fornecido: The name of this header is your product module name followed by adding "-Swift.h".Portanto, não é o nome da classe como você escreveu, mas o nome do seu módulo de produto e que importa a importação de todos os arquivos rápidos, não apenas de um específico
Chris
4

Pesquise "Nome do cabeçalho da interface gerada pelo Objective-C" nas Configurações de compilação do destino que você está tentando compilar (digamos que seja MyApp-Swift.h) e importe o valor dessa configuração ( #import "MyApp-Swift.h") no arquivo de origem onde você está tentando acessar suas APIs Swift.

O valor padrão para este campo é $(SWIFT_MODULE_NAME)-Swift.h. Você pode vê-lo se clicar duas vezes no campo de valor da configuração "Nome do cabeçalho da interface gerada por Objective-C".

Além disso, se você tiver traços no nome do módulo (digamos que seja My-App), $(SWIFT_MODULE_NAME)todos os traços serão substituídos por sublinhados. Então você terá que adicionar #import "My_App-Swift.h".

Misha Karpenko
fonte
Melhor que o aprovado. Os traços perderam 20 min. Eu nunca voltarei haha.
precisa
3

Se você deseja usar o arquivo Swift na classe Objective-C , então a partir do Xcode 8 você pode seguir as etapas abaixo:

Se você criou o projeto no Objective-C:

  1. Crie um novo arquivo Swift
  2. O Xcode solicitará automaticamente o arquivo Bridge-Header
  3. Gere-o
  4. Importe "ProjectName-Swift.h" no seu controlador Objective-C (importe na implementação não na interface) (se o seu projeto tiver espaço entre o nome, use o sublinhado "Project_Name-Swift.h")
  5. Você poderá acessar sua classe Objective-C no Swift.

Compile-o e se ele irá gerar um erro de vinculador, como: compilado com a versão mais recente da linguagem Swift (3.0) que os arquivos anteriores (2.0) para a arquitetura x86_64 ou armv 7

Faça mais uma alteração no seu

  1. Xcode -> Projeto -> Alvo -> Configurações de compilação -> Usar versão do idioma Swift herdado -> Sim

Construir e executar.

Dheeraj D
fonte
1
eu não estou recebendo esta opção de versão uso legado linguagem rápida
rd_
1

Tenha cuidado com traços e sublinhados, eles podem ser misturados e o nome do projeto e o nome do destino não serão os mesmos que SWIFT_MODULE_NAME.

Traços e sublinhados

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

você verá quando você digitar no teclado #import <e depois automaticamente o Xcode o aconselhará.

Erhan Demirci
fonte
-1

Encontre o arquivo .PCH dentro do projeto. e adicione #import "YourProjectName-Swift.h"Isto importará os cabeçalhos da classe. Para que você não precise importar para um arquivo 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.
fonte