Observe que alguns considerariam o uso do delegado do aplicativo como um contêiner para o contexto de objeto gerenciado ou outros objetos "globais" como um antipadrão. Considere pedir ao delegado do aplicativo que passe o MOC para o controlador, em vez de fazer com que o controlador o encontre.
precisa
1
@KristopherJohnson Hey Kris, como posso facilitar o AppDelegate que injeta dependências nos controladores de exibição? Instancie o controlador de exibição programaticamente e use a reflexão para decidir o que instanciar / injetar, recursivamente? Existem estruturas que podem ajudar com isso? Se eu tiver que fazer isso manualmente para cada controlador de exibição, meu AppDelegate será enorme! Oh, de preferência sem a criação de uma fábrica para tudo :)
Jimbo
1
Uma busca rápida encontrada Swinject que também tem auto-fiação :)
Jimbo
6
Para os programadores que desaconselham colocar nada "estranho" na delegado do aplicativo, que é um pouco absurdo, porque a documentação da Apple afirma explicitamente que a "crucial role"do UIApplicationDelegateSingleton é "...to store your app’s central data objects or any content that does not have an owning view controller."developer.apple.com/documentation/uikit/uiapplicationdelegate
BSOD
Respostas:
757
A outra solução está correta, pois fornecerá uma referência ao delegado do aplicativo, mas isso não permitirá que você acesse quaisquer métodos ou variáveis adicionados pela sua subclasse de UIApplication, como o contexto do objeto gerenciado. Para resolver isso, basta fazer o downcast para "AppDelegate" ou como sua subclasse UIApplication é chamada. Nos Swift 3, 4 e 5 , isso é feito da seguinte maneira:
let appDelegate =UIApplication.shared.delegate as!AppDelegatelet aVariable = appDelegate.someVariable
Caso alguém ainda esteja tendo problemas, o direcionamento para o OS X exige que você importe o Cocoa para que isso funcione no NSApplication.sharedApplication (). Eu acho que o iOS precisaria do equivalente.
precisa saber é
2
Essa é a mais útil das duas respostas.
Joe
3
@zacjordaan Usando esse método, você obterá o preenchimento automático da propriedade, mas na verdade não funcionará. Dessa forma, criará uma nova instância da classe AppDelegate toda vez que você a usar. É melhor usar o delegado acessível por meio do singleton sharedApplication. E no que diz respeito à sua segunda pergunta, sim, você provavelmente deseja usar uma constante. Mesmo assim, você pode estar alterando as propriedades do AppDelegate, provavelmente não irá atribuir o ponteiro a mais nada; nesse caso, não há necessidade de uma variável. Isso é completamente com você, no entanto. Faça o que se adequa às suas necessidades.
Mick MacCallum
2
Excelente conselho! Por engano, pensei que AppDelegate () era único, mas depois de pensar no que você disse, percebi que, se fosse, não haveria um padrão de aplicativo compartilhado para usarmos dessa maneira. É claro que não quero gerar instâncias desnecessárias, se não for necessário, para que sua declaração constante sirva perfeitamente; Obrigado.
zacjordaan
4
Não quero adicionar isso como resposta separada, mas para obter o AppDelegate com seus próprios métodos, propriedades no projeto em que são usados um Swift e um Obj-c. Você deve adicionar #import "AppDelegate.h" a "ProjectName-BridgingHeader .h "
Seria ótimo explicar o que setRoot () faz e quando chamá-lo. por exemplo, está tudo bem chamá-lo de um ViewController? Em um teste de unidade em que a janela ainda não está definida? Mais contexto seria ótimo.
Houman
@Houman setRoot é um método do AppDelegate que pode ser usado para alternar entre várias raízes ou ParentViewController e pode ser qualquer método. A discussão é sobre como obter a referência do AppDelegate para acesso adicional, mas espero que o setRoot também seja claro.
27419 AiOsN
19
É praticamente o mesmo que no Objective-C
let del =UIApplication.sharedApplication().delegate
isso também funciona, e eu gosto da ideia da nomeação sharedInstance. obrigado!
John Griffiths
2
Seu exemplo ainda instanciar um novo AppDelegateobjeto de cada vez que você ligouAppDelegate().sharedInstance()
pxpgraphics
1
Eu gosto mais desta solução do que a solução aceita (que é "sem sentido", se você precisar usá-la toda). Eu estava pensando em experimentar um extensionfor NSApplicationantes de encontrar essa resposta, mas isso é muito melhor. Atualmente, você provavelmente desejaria usar uma propriedade somente leitura de classe shared, talvez você queira publicar uma atualização para o Swift 3?
Patru 25/05
1
Na verdade, estou refatorando meu código para usar, o static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }que está mais de acordo com o estilo Swift 3 em desenvolvimento de usar propriedades computadas somente leitura para esse tipo de coisa. Provavelmente poderei largar a ?vez que a refatoração estiver concluída, você não acha? (Desculpe, formatação de código em comentários é sempre uma bagunça.)
Patru
@ pxpgraphics O UIApplication é uma classe singleton, portanto, não é necessário se preocupar com instanciações múltiplas.
Abhijith 4/17/17
10
Além do que é dito aqui, no meu caso, perdi a importação do UIKit:
Aqui está uma extensão UIApplicationDelegateque evita a codificação do AppDelegatenome da classe:
extensionUIApplicationDelegate{staticvar shared:Self{returnUIApplication.shared.delegate!as!Self}}// use like this:
let appDelegate =MyAppDelegate.shared // will be of type MyAppDelegate
no Mac por NSApplicationDelegateisso me dá: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Isso está desatualizado?
Pkamb #
@pkamb Acabei de experimentar em um novo projeto e não tenho esse erro. Eu substituí UIApplicationDelegatepor NSApplicationDelegatee UIApplicationpor NSApplication.
Nyg 07/11/19
5
Assegure-se de que você import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
No meu caso, estava faltando import UIKitem cima da minha NSManagedObjectsubclasse. Depois de importá-lo, eu poderia remover esse erro, como UIApplicationfaz parte doUIKit
A partir do iOS 12.2 e Swift 5.0, AppDelegatenão é um símbolo reconhecido. UIApplicationDelegateé. Quaisquer respostas referentes a, AppDelegateportanto, não estão mais corretas. A resposta a seguir está correta e evita o desempacotamento forçado, que alguns desenvolvedores consideram um cheiro de código:
"crucial role"
doUIApplicationDelegate
Singleton é"...to store your app’s central data objects or any content that does not have an owning view controller."
developer.apple.com/documentation/uikit/uiapplicationdelegateRespostas:
A outra solução está correta, pois fornecerá uma referência ao delegado do aplicativo, mas isso não permitirá que você acesse quaisquer métodos ou variáveis adicionados pela sua subclasse de UIApplication, como o contexto do objeto gerenciado. Para resolver isso, basta fazer o downcast para "AppDelegate" ou como sua subclasse UIApplication é chamada. Nos Swift 3, 4 e 5 , isso é feito da seguinte maneira:
fonte
Swift 4.2
No Swift, fácil acesso nos VCs
fonte
Construtores de conveniência
Swift 5
Para usar a referência AppDelegate em sua classe?
fonte
É praticamente o mesmo que no Objective-C
fonte
Isso pode ser usado para o OS X
fonte
let appDelegate = NSApp.delegate as AppDelegate
let appDelegate = NSApplication.shared().delegate as AppDelegate
NSApp.delegate as? AppDelegate
Aqui está a versão Swift 2.0:
E para acessar o contexto do objeto gerenciado:
ou, usando guarda:
fonte
SWIFT <3
Crie um método na classe AppDelegate para ex
e chamá-lo em algum outro lugar para ex
SWIFT> = 3.0
fonte
AppDelegate
objeto de cada vez que você ligouAppDelegate().sharedInstance()
extension
forNSApplication
antes de encontrar essa resposta, mas isso é muito melhor. Atualmente, você provavelmente desejaria usar uma propriedade somente leitura de classeshared
, talvez você queira publicar uma atualização para o Swift 3?static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }
que está mais de acordo com o estilo Swift 3 em desenvolvimento de usar propriedades computadas somente leitura para esse tipo de coisa. Provavelmente poderei largar a?
vez que a refatoração estiver concluída, você não acha? (Desculpe, formatação de código em comentários é sempre uma bagunça.)Além do que é dito aqui, no meu caso, perdi a importação do UIKit:
fonte
Tente simplesmente o seguinte:
Swift 4
onde no seu AppDelegate:
fonte
Aqui está uma extensão
UIApplicationDelegate
que evita a codificação doAppDelegate
nome da classe:fonte
NSApplicationDelegate
isso me dá:'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?
. Isso está desatualizado?UIApplicationDelegate
porNSApplicationDelegate
eUIApplication
porNSApplication
.Assegure-se de que você
import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
fonte
É muito simples
Instância de delegação de aplicativo
você pode chamar um método com sintaxe de uma linha
você pode acessar uma variável com este código
fonte
No meu caso, estava faltando
import UIKit
em cima da minhaNSManagedObject
subclasse. Depois de importá-lo, eu poderia remover esse erro, comoUIApplication
faz parte doUIKit
Espero que ajude os outros !!!
fonte
Eu uso isso no Swift 2.3.
1. na classe AppDelegate
2.Call AppDelegate com
fonte
fonte
A partir do iOS 12.2 e Swift 5.0,
AppDelegate
não é um símbolo reconhecido.UIApplicationDelegate
é. Quaisquer respostas referentes a,AppDelegate
portanto, não estão mais corretas. A resposta a seguir está correta e evita o desempacotamento forçado, que alguns desenvolvedores consideram um cheiro de código:fonte
fatalError
é funcionalmente equivalente a uma força desembrulhada!No Swift 3.0, você pode obter a
appdelegate
referência porfonte
No Xcode 6.2, isso também funciona
fonte