“Uso de tipo não declarado” no Swift, mesmo que o tipo seja interno e exista no mesmo módulo

173

Eu tenho um tipo no meu módulo:

import Cocoa

class ColoredDotView : NSView {
   ...
}

É usado em várias classes diferentes sem problemas:

class EditSubjectPopoverController : NSObject {

    @IBOutlet internal var subjectColorDotView : ColoredDotView!
    ...
}

Mas, por algum motivo , quando eu o uso em uma classe específica , tenho erros de compilação no tipo:

class EditTaskPopoverController : NSObject {

    @IBOutlet internal var lowPriorityDotView : ColoredDotView! // Error here
    @IBOutlet internal var medPriorityDotView : ColoredDotView! // And here...
    @IBOutlet internal var highPriorityDotView : ColoredDotView! // And here...
    ...
}

O erro de compilação é:

EditTaskPopoverController.swift: 15: 49: Uso do tipo não declarado 'ColoredDotView'

O que eu não entendo. É o primeiro erro de compilação no arquivo, e o restante dos erros é sintomático do primeiro. Além disso, não há outros arquivos com erros de compilação. Não entendo por que o tipo não é declarado, pois o arquivo está no mesmo módulo:

insira a descrição da imagem aqui

Eu tentei limpar o projeto, limpar a pasta de compilação e reiniciar o Xcode, sem sucesso. Quais erros em potencial podem causar um undeclared typeerro de compilação no Swift?

Craig Otis
fonte
Já tive muitos casos em que o erro real está algumas linhas (ou mais) mais abaixo e o Xcode identifica erroneamente algo inócuo com uma mensagem de erro. Veja se você pode obter esse erro para ir embora, apagando o resto do seu código, em seguida, adicione-o de volta pouco a pouco ...
Nate Cozinhe
Obrigado Nate - infelizmente, removo as vardeclarações e chego a uma versão passageira. Depois, adiciono uma das declarações na parte superior e o erro volta imediatamente: imgur.com/VUUBK2K
Craig Otis

Respostas:

200

Para mim, encontrei esse erro quando meu destino de teste não tinha alguns arquivos rápidos que meu destino de criação de aplicativos tinha em fontes de compilação. Foi muito confuso porque o 'tipo não declarado' estava sendo usado em muitos outros lugares sem problemas, e o erro parecia vago. Portanto, é claro que a solução foi adicionar o arquivo que contém o 'tipo não declarado' ao destino do teste.

mattorb
fonte
2
O mesmo para mim: o problema ocorre quando uma classe usada por outra incluída no alvo de teste também não é incluída no alvo de teste! (╯ ° □ °) ╯︵ ┻━┻
Francesco Vadicamo /
2
Você acabou de resolver um problema que me incomodou por meia hora. Eu havia importado algumas classes Swift anteriores para um projeto atual, mas obviamente ainda não havia adicionado as classes mais antigas ao destino do teste. Mas o preenchimento automático me levou a pensar que estava tudo bem ... até que eu tentei construir e executar. O que...! Muito obrigada.
Jim Hillhouse
2
Isso resolveu o problema para mim também. Eu havia clicado em um arquivo e o arquivo-> duplicado uma cópia dele. A nova cópia foi listado mas não incluídos nas "fontes de compilação"
Ron Myschuk
1
No meu caso eu tinha selecionado 3 alvos (testes Projeto, UI & unidade), eu tive que desmarcar UI & Unidade testa alvos a fim de resolver este erro
Frakcool
1
"Solução, é claro ..." pressupõe que o leitor entenda como adicionar a meta de teste. Para nós, começando com o Xcode, não é um momento "claro ...". Votei na resposta de @ edwin quando ele terminou sua resposta.
Michael
181

Isso já foi respondido por @Craig Otis, mas o problema é causado quando as classes em questão não pertencem aos mesmos destinos, geralmente o destino de teste está ausente. Apenas verifique se as seguintes caixas de seleção estão marcadas.


associação de destino

Editar

Para ver a associação de destino. Selecione seu arquivo e abra o inspetor de arquivos (⌥ + ⌘ + 1) [ opção ] + [ comando ] + 1

descrição detalhada

Edwin
fonte
não tenho certeza, mas quando desmarco o destino "TEST" (nesse caso, é YAWA-WeatherTest). construiu sem erro.
dellos
Você pode esclarecer onde está no XCode para definir essa associação de destino? Não me lembro de ter visto isso antes. Obrigado.
Casey Perkins
2
De fato, desmarque a meta de teste, pois é por isso que "importamos testável ..." nos projetos de teste.
empate ..
A captura de tela é muito útil. Obrigado!
Michael
37

Ufa, finalmente diagnosticou isso. De alguma forma , o arquivo Swift ofensivo EditTaskPopoverController.swiftestava em duas fases diferentes de compilação.

Ele estava Compile Sourcescorretamente, com todos os outros arquivos Swift, mas também estava , por algum motivo muito estranho, na Copy Bundle Resourcesfase, junto com todos os meus recursos XIB e de imagem.

Não tenho ideia de como chegou lá, mas removê-lo da fase extra de compilação resolveu o problema.

Craig Otis
fonte
Acabei tendo o mesmo problema, porque estava usando github.com/kronenthaler/mod-pbxproj e swift, acidentalmente adicionei swift aos tipos como PBXResourcesBuildPhase em vez de PBXSourcesBuildPhase em mod-pbxproj
rich
2
Companheiro! O salva-vidas estava destruindo minha cabeça por causa disso. Cheers
SparkyRobinson
27

No menu XCode, Produto-> Limpo e, em seguida, Produto-> Construção funcionou para mim. Encontrei esse problema quando adicionei um novo ViewController ao meu projeto no novo Grupo / Pasta.

Matriz
fonte
5
2 horas, e nunca pensei em clicar no botão de compilação para incorporar a estrutura depois de instalar um pod ... vou sair agora ...
Cruceo
1
Perdeu muito tempo tentando outras respostas, mas nunca limpou e construiu. Muito obrigado
Zeero0
Eu tive esse erro ao jogar com o SwiftUI no Xcode 11.0 beta 5, enquanto seguia o tutorial da Apple. A tela exibia corretamente outros arquivos, mas um arquivo adicionado recentemente gerou esse erro, dizendo que LandmarkRow_Previews era um tipo não declarado. Apenas a compilação limpa corrigiu o problema.
salo.dm 3/08/19
Esta resposta é equivalente ao suporte técnico: "Você tentou reiniciar o dispositivo?" Uma boa dica :)
turingtested 27/03
14

Eu tive o mesmo problema. Alguns dos arquivos em minha estrutura não estavam acessíveis a partir de outras classes dentro do mesmo módulo.

Por alguma razão, os arquivos que foram adicionados à estrutura no Xcode não faziam parte das fontes de compilação. Se o seu arquivo Swift não faz parte das fontes de compilação, você precisa adicioná-los tocando no + e selecionando-os no pop-up.

Captura de tela 1

Verifique também se o arquivo faz parte do destino da estrutura. (A pequena caixa na imagem abaixo deve estar marcada)

Captura de tela 2

Groot
fonte
12

A causa para mim foi um nome de função que começou com os mesmos caracteres que um tipo:

@IBOutlet weak var tableView: CustomTableView!

e na implementação eu tive uma função começando com CustomTableView

func CustomTableView(tableView: CustomTableView, dataForRow row:  Int) -> NSData {...}

A correção foi alterar a assinatura da função para que não começasse com os mesmos caracteres do tipo (CustomTableView), por exemplo:

func dataForRow(row: Int, tableView: CustomTableView) -> NSData {...}

Esta foi uma mensagem de erro muito enganadora para a causa real no meu caso.

Andrew
fonte
1
Muito obrigado por postar essa correção, Andrew, foi uma grande ajuda. A mensagem de erro é certamente enganosa.
Jjc99
7

Caso alguém encontre um problema semelhante, mas a correção do Compile Sources não resolva o problema, reiniciar o Xcode pode (funcionou para mim). Minha versão do Xcode é Version 6.1 (6A1052d).

lindon fox
fonte
Reiniciar funcionou para mim, embora o erro tenha surgido novamente após uma compilação bem-sucedida, sem nenhuma alteração adicional no código.
Incomum
Reiniciar o Xcode corrige tantos problemas que a Apple realmente deveria fazer algo a respeito.
Forge
5

No meu aplicativo, tenho delegado de aplicativo e outras classes que precisam ser acessadas pelos testes como públicas. Conforme descrito aqui , importo meu aplicativo em meus testes.

Quando criei duas novas classes recentemente, seus alvos de teste eram as partes principal e de teste. Removê-los da associação dos testes resolveu o problema.

Nate Uni
fonte
5

No meu caso, as fontes de compilação do TestTarget estavam tendo arquivos do Main Target .

Ref :

O destino de teste contém arquivos do destino principal na guia fontes de compilação

Por que isso acontece?

  • Isso acontece desde que verificamos a associação TestTarget ao criar o arquivo

  • Ou marque manualmente esta opção no inspetor.

    Ref :

    Criar arquivo - o destino do teste está marcado

Como eu resolvi?

  • Eu removi os arquivos do alvo principal da fonte de compilação do Test Target
Ratz
fonte
5

Às vezes, os erros podem ser muito bobos

Antes de verificar todas as soluções aqui, verifique se importou todas as coisas básicas

     import Foundation
     import UIKit

É bem possível que, quando você importe alguns arquivos de fora para o seu projeto, o que pode perder essas coisas básicas, como experimentei uma vez.

Suraj K Thomas
fonte
aconteceu comigo no CLLocationManagerDelegate e tudo o que eu precisava fazer era importar o CoreLocation nesse outro arquivo, como por que eu perdi 20 minutos?
derek
4

Tentei muitas das soluções oferecidas aqui, mas, eventualmente, excluí o arquivo e o criei novamente, e o Xcode foi modificado: /

Yusuf X
fonte
Isso funcionou para mim também. Removida a referência, limpa, compila e adiciona o arquivo novamente.
andnil
OBRIGADO! Isso é muito bizarro. Apenas funcionou para mim também. O código antigo antigo copiado e apagado para o novo arquivo nem precisava ser limpo / compilado.
timman 6/04
4

Isso também pode acontecer se você acidentalmente capitalizar o nome do parâmetro e chamá-lo da mesma forma que o objeto.

class func didRecieveData(BlockItems: [BlockItems])
Rindom
fonte
3

Isso pode ajudar alguém.

Eu criei um novo projeto de teste com o Core Data chamado "CoreData". Em pouco tempo, recebi "Uso de tipo não declarado" para NSManagedObjectContext e outras classes de dados principais. Após várias tentativas de importação, adicionando às fases de compilação, etc. Excluí o projeto e iniciei um novo chamado "TestingCoreData" e tudo funcionou bem.

Não nomear (testar) projetos como o nome das classes

Babac
fonte
3

Isso também pode acontecer se você tiver uma função com o mesmo nome que um tipo de objeto em sua assinatura. Por exemplo:

class func Player(playerObj: Player)

fará com que o compilador fique confuso (e com razão), pois o compilador primeiro procurará localmente no arquivo antes de examinar outros arquivos. Então ele olha para "Player" na assinatura e pensa que não é um objeto nesse escopo, mas uma função, então algo está errado.

Talvez essa seja uma boa razão para eu não capitalizar as funções de classe. :)

Maxwell
fonte
3

Recebi essa mensagem de erro no Xcode 8 ao refatorar o código em uma estrutura, mas esqueci de declarar a classe na estrutura como public

tsuchi.one
fonte
2

Talvez você tenha adicionado classe com alguns "FirstNameClass" e depois renomeado manualmente para "ColoredDotView". Tente copiar o conteúdo da classe "ColoredDotView" para a área de transferência, remova "ColoredDotView" do projeto e adicione novamente.

Esse id resolve um problema semelhante de mim.

Almin
fonte
2

No meu caso, foi um erro cometido por mim. Adicionei um novo arquivo como "OS X> Origem> Classe Cocoa", em vez de "iOS> Origem> Classe Cocoa Touch".

Javier Calatrava Llavería
fonte
2

No meu caso, isso foi causado por um nome de subclasse sendo usado na linha seguinte, como um nome de variável com um tipo diferente:

var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlow: PipGlowSprite = PipGlowSprite()

Observe que na linha 1, pipGlow é o nome da subclasse (de SKShapeNode), mas na linha dois, eu estava usando pipGlow como um nome de variável. Este não era apenas um estilo de codificação ruim, mas aparentemente um não-não definitivo também! Depois de alterar a segunda linha para:

var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlowSprite: PipGlowSprite = PipGlowSprite()

Não recebi mais o erro. Espero que isso ajude alguém!

zeeple
fonte
2

Ao testar o código Swift que pertence ao aplicativo, verifique primeiro se o destino do teste está criando o aplicativo como uma dependência. Em seu teste, importe o aplicativo como um módulo. Por exemplo:

@testable import MyApplication

Isso tornará os objetos Swift que fazem parte do aplicativo disponíveis para o teste.

quellish
fonte
2

No meu caso, isso foi causado pela codificação de texto dos arquivos rápidos. Um arquivo mostrou 'No Explicit Encoding' e, depois de convertido para 'UTF-8', o problema foi resolvido.

E a razão pela qual a codificação de texto do arquivo não é explícita é que copiei todo o código de outro arquivo rápido.

Nenhuma captura de tela explícita da codificação

insira a descrição da imagem aqui

Captura de tela UTF-8

insira a descrição da imagem aqui

Jirui
fonte
2

A limpeza do projeto resolveu meu problema.

Etapas: Produto -> Limpar (ou Shift + Cmd + K)

Anshul Tiwari
fonte
1

No meu caso, eu queria adicionar um método com um objeto swift personalizado como um parâmetro de tipo, e o nome que dei à variável no parâmetro era exatamente o mesmo que o nome da classe de objeto personalizado

Os problemas eram algo assim:

func moveBlob(**blob** : blob){
    ...code
}

A parte em negrito estava causando o erro do tipo não declarado

cmario
fonte
1

como outros mencionados bem e neste tópico

uso de arquivos rápidos desnecessários em "copiar recursos do pacote" captura de tela para ajudar

Hamed Nova
fonte
1

Como outros, era algum código não relacionado que estava causando o @testablemau funcionamento.

No meu alvo de teste, havia um arquivo de cabeçalho Objective-C que tinha

@import ModuleUnderTest;

Eu removi esta linha (porque a importação era realmente desnecessária) e milagrosamente comecei @testablea trabalhar novamente.

Eu só consegui rastrear isso, mas removi tudo do meu projeto e o adicionei novamente pouco a pouco até que falhou. Eventualmente, encontrei a linha do código com problema.

Oliver Pearmain
fonte
1

se você está acessando através de diferente moduleou Targetentão você só precisa dele para publicele

Sultan Ali
fonte
1

Caso alguém cometa o mesmo erro bobo que eu cometi ...

Eu estava recebendo esse erro porque, ao renomear meu arquivo de origem, removi acidentalmente .o nome do arquivo e, portanto, o compilador tratou o arquivo como um arquivo de texto sem formatação e não como fonte para compilar.

então eu quis mudar o nome do arquivo, MyProtocol.swift mas acidentalmente o nomeei MyProtocolswift

É um erro simples, mas não era óbvio que era isso que estava acontecendo.

Marc Renaud
fonte
1

Não adicionar a remcartação de importação correta também pode ser uma falha óbvia. Para mim, simplesmente omiti a importação do PriorityUIKit.

Carimbo
fonte
1

Minha situação é que eu arrasto um novo arquivo XXView.swift para o projeto. E declare um tipo de exibição como XXView, em seguida, o erro "uso do tipo não declarado ....".

Eu apenas tento adicionar meu XXView.swift ao destino do teste, que resolveu o erro. Mas eu não queria que minha classe de interface do usuário estivesse envolvida no destino do teste.

Finalmente, encontrei meu ViewController já no alvo de teste, o que não deveria acontecer. (Eu acho que porque eu criei o VC por um xctemplate, portanto, ele será automaticamente incluído no destino do teste)

Eu removo o controlador de exibição do alvo de teste e, agora, meu XXView não precisa mais ser adicionado ao alvo de teste.

Conclusão: verifique se todos os arquivos relacionados também devem desmarcar o destino do teste.

Wangdu Lin
fonte
1

Depois de passar uma hora com esse erro, descobri que o arquivo do módulo está duplicado. exclua o arquivo extra e desloque + cmd + k para limpar e o erro desaparece.

Alirza Eram
fonte
Esta pode ser uma pergunta estúpida, mas você pode explicar mais sobre isso? Isso acontece também com arquivos rápidos duplicados ou com grupos duplicados etc.? Funcionou, mas eu gostaria de saber mais sobre o porquê de funcionar do que apenas aceitar que funciona. Obrigado pela solução, a propósito!
Cody Vollrath
1

No meu caso, o problema foi com um novo classnão sendo reconhecido. Resolvi o problema excluindo a classe e re-adicionando-a, mas desta vez verificando a Watch App Extensionopção ao criar a nova classe.

insira a descrição da imagem aqui

Observe que eu tenho uma extensão de aplicativo de exibição no meu aplicativo.

fs_tigre
fonte
Obrigado e, no meu caso, também só precisava adicionar o arquivo para o correto Target.
coletrain