Xcode 6 / Beta 4: o uso de cabeçalhos de ponte com destinos de estrutura não é suportado

131

Acabei de atualizar para o Xcode 6 Beta 4 e tenho uma estrutura que criei para o Live Views no Beta 2. Devido a outro bug rápido , eu precisava usar algum código Obj-C. Ao atualizar, porém, recebo o seguinte erro:

erro: o uso de ponte de cabeçalhos com destinos de estrutura não é suportado

Não vi nada nas notas de versão nem encontrei outro caminho de migração. Alguém mais viu isso e chegou a uma solução?

Percebo que o Beta 3 eliminou a necessidade de estruturas para exibições ao vivo, mas faz sentido no meu caso se eu conseguir fazê-lo funcionar. Posso removê-lo como um substituto, mas preferiria usar uma estrutura se eles não estiverem totalmente quebrados no Beta 4.

Chris Conover
fonte
"Percebo que o Beta 3 eliminou a necessidade de estruturas". Quão?
hnh 21/07
2
(para visualizações ao vivo) - editado
Chris Conover
1
Estou com o mesmo problema.
Simon Germain
2
Uau, sua pequena edição lá apenas tornou minha vida muito melhor - não ouvi falar dessa mudança (eliminando a necessidade de estruturas) em qualquer lugar e estava batendo minha cabeça com todos esses destinos de estrutura para exibições ao vivo por horas. Muito obrigado por esta @chrisco!
Yonix 14/10

Respostas:

232

Como declara o erro, não são permitidos colmatar cabeçalhos no Frameworks. A seção Importando código de dentro do mesmo destino de estrutura da documentação da Apple Mix & Match sugere isso. Como se costuma dizer, você precisa "No arquivo de cabeçalho do seu guarda-chuva, importe todos os cabeçalhos de Objective-C que deseja expor para o Swift".

No entanto, descobri que você também pode precisar tornar públicos esses cabeçalhos específicos. Esta resposta analisa por que e como fazer isso: Erro do compilador Swift: "cabeçalho não modular dentro do módulo de estrutura" .

Então, faça o seguinte:

  1. Remova o arquivo de cabeçalho da ponte.
  2. Remova as referências ao arquivo de cabeçalho da ponte nas configurações de construção da estrutura
  3. Adicione os cabeçalhos necessários ao seu arquivo guarda-chuva ([ProductName] .h)
  4. Torne os arquivos incluídos públicos na seção "Cabeçalhos" da estrutura de "Fases de construção".
  5. Limpe e reconstrua.

Nota : O "arquivo de cabeçalho guarda-chuva" é um arquivo (chamado [NomeDoProduto] .h) que geralmente representa todos os cabeçalhos públicos de uma estrutura. Geralmente, é apenas uma lista de #import declarações para outros cabeçalhos contidos na estrutura. No Xcode, se você abrir o UIKit.h, verá um bom exemplo de um arquivo guarda-chuva.

DeepFriedTwinkie
fonte
3
Obrigado pela resposta sucinta (marcada como tal). Eu tinha lido essa seção, mas estava confuso quanto à distinção entre o cabeçalho da Umbrella e a ponte.
22614 Chris Conover
1
@ zaxy78, consulte a seção "Importando o Swift para o Objective-C" deste documento: developer.apple.com/library/ios/documentation/Swift/Conceptual/…
DeepFriedTwinkie
4
@DeepFriedTwinkie, a que arquivo guarda-chuva você se refere quando diz: "Adicione os cabeçalhos necessários ao seu arquivo guarda-chuva"? Obrigado.
Allan Macatingrao
2
Isso é exatamente o que eu precisava. Adicioná-los à seção pública foi a correção.
precisa saber é o seguinte
20
Estou correto ao supor que qualquer classe que eu queira manter privada em minha estrutura que deva ser usada por uma classe rápida deve agora ser tornada pública para qualquer pessoa que use minha estrutura? Não parece uma solução ideal.
Ospr
28

Existem duas possibilidades. Adicionar os cabeçalhos necessários ao arquivo de cabeçalho guarda-chuva e torná-los públicos é uma maneira. No entanto, isso é um problema se os cabeçalhos estiverem disponíveis para o Swift, mas não para o público.

A segunda possibilidade que disponibilizará cabeçalhos internos para o Swift é descrita em detalhes aqui . Essencialmente, é necessário criar um mapa de módulo semelhante ao seguinte:

module AwesomeKitPrivate {  
  header "../InternalClass.h"
  export *
}

Isso pode ser incluído no XCode usando a configuração:

SWIFT_INCLUDE_PATHS = $(SRCROOT)/AwesomeKit/ProjectModule  
Jan Rüegg
fonte
2
Excelente! Obrigado. Técnica muito preferida a tornar públicos todos os cabeçalhos.
21718 David David H
Aconselhamos que a solução contra os outros, e procurar o link fornecido para solução detalhada
Tancrede Chazallet
Esta é a resposta certa, mas dependendo do que você está tentando alcançar, você pode se safar do uso de algumas macros fornecidas pela Apple, que ajudam muito na interoperabilidade do Swift-Objc: developer.apple.com/documentation/swift/ …
Joe Susnick 12/08/19
A headerdeclaração aceita um caminho relativo. O que você faz quando deseja adicionar os cabeçalhos de outra estrutura?
Georgios
13

Consulte Importando Objective-C para Swift .

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

  1. Em Configurações de compilação, em Empacotamento, verifique se a configuração Define Module para esse destino da estrutura está definida como "Sim".
  2. No seu arquivo de cabeçalho guarda-chuva, importe todos os cabeçalhos Objective-C que você deseja expor para o Swift. Por exemplo:

        #import "XYZ / XYZCustomCell.h"
        #import "XYZ / XYZCustomView.h"
        #import "XYZ / XYZCustomViewController.h"
    
  3. Torne os arquivos incluídos públicos na seção "Cabeçalhos" da estrutura de "Fases de construção".

  4. Limpe e reconstrua.

O Swift verá todos os cabeçalhos expostos publicamente no cabeçalho do seu guarda-chuva. O conteúdo dos arquivos Objective-C nessa estrutura estará disponível em qualquer arquivo Swift dentro desse destino da estrutura automaticamente, sem nenhuma declaração de importação. Use seu código Objective-C personalizado com a mesma sintaxe Swift usada nas classes do sistema.

let myOtherCell = XYZCustomCell()
myOtherCell.subtitle = "Another custom cell"

Importante: o "arquivo de cabeçalho guarda-chuva" significa o arquivo {ModuleName} .h. BTW, o nome do destino é {ModuleName} .framework.

Ralph Shane
fonte
1
Eu quero usar arquivos objc dentro do arquivo Swift dos meus módulos, mas não quero expô-los a outros módulos. Como posso fazer isso?
Sazzad Hissain Khan 4/12/19
0

No meu caso, apenas remover a Objective-C Bridging Headerconfiguração da minha estrutura Build Settingsajudou.

insira a descrição da imagem aqui

Denis Kutlubaev
fonte