Notez que certains considéreraient l'utilisation du délégué d'application comme conteneur pour le contexte d'objet géré ou d'autres objets «globaux» comme un anti-modèle. Pensez à demander au délégué de l'application de passer le MOC au contrôleur, plutôt que de le faire le trouver.
Kristopher Johnson
1
@KristopherJohnson Hey Kris, comment puis-je faciliter l'injection de dépendances AppDelegate dans les contrôleurs de vue? Instancier le contrôleur de vue par programme et utiliser la réflexion pour décider quoi instancier / injecter, récursivement? Y a-t-il des cadres qui peuvent aider à cela? Si je dois faire cela pour chaque contrôleur de vue manuellement, mon AppDelegate va être énorme! Oh, de préférence sans créer une usine pour tout :)
Jimbo
1
Une recherche rapide a trouvé Swinject qui a également un câblage automatique :)
Jimbo
6
Pour les programmeurs qui déconseillent de mettre quoi que ce soit d '"étranger" dans le délégué de l'application, c'est un peu absurde car la documentation Apple indique explicitement que l'un "crucial role"des UIApplicationDelegatesingleton est "...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
Réponses:
757
L'autre solution est correcte dans la mesure où elle vous fournira une référence au délégué de l'application, mais cela ne vous permettra pas d'accéder aux méthodes ou variables ajoutées par votre sous-classe d'UIApplication, comme votre contexte d'objet géré. Pour résoudre ce problème, il vous suffit de passer à "AppDelegate" ou à ce que votre sous-classe UIApplication soit appelée. Dans Swift 3, 4 et 5 , cela se fait comme suit:
let appDelegate =UIApplication.shared.delegate as!AppDelegatelet aVariable = appDelegate.someVariable
Dans le cas où quelqu'un a toujours des problèmes, le ciblage d'OS X nécessite que vous importiez Cocoa pour que cela fonctionne pour NSApplication.sharedApplication (). Je suppose que iOS aurait besoin de l'équivalent.
smaurice
2
C'est la plus utile des deux réponses.
Joe
3
@zacjordaan En utilisant cette méthode, vous obtiendrez la saisie semi-automatique pour la propriété, mais cela ne fonctionnera pas réellement. De cette façon, vous créerez une nouvelle instance de la classe AppDelegate chaque fois que vous l'utiliserez. Il vaut mieux utiliser le délégué accessible via le singleton sharedApplication. Et en ce qui concerne votre deuxième question, oui, vous voulez probablement utiliser une constante. Même si vous modifiez peut-être les propriétés de AppDelegate, vous ne réaffecterez probablement pas le pointeur à autre chose, auquel cas, il n'y a pas besoin de variable. Cela dépend entièrement de vous. Faites ce qui convient à vos besoins.
Mick MacCallum
2
Un excellent conseil! J'avais pensé à tort que AppDelegate () était singleton mais après avoir réfléchi à ce que vous avez dit, je me suis rendu compte que si c'était le cas, il n'y aurait pas de modèle d'application partagée à utiliser de cette manière. Bien sûr, je ne veux pas engendrer d'instances inutiles si je n'ai pas à le faire, donc votre déclaration constante conviendra parfaitement; Je vous remercie.
zacjordaan
4
Je ne veux pas ajouter ceci comme réponse distincte, mais pour obtenir AppDelegate avec vos propres méthodes, propriétés dans le projet où un Swift et un Obj-c sont utilisés Vous devez ajouter #import "AppDelegate.h" à "ProjectName-BridgingHeader .h "
Ce serait bien d'expliquer ce que fait setRoot () et quand l'appeler. par exemple, est-il correct de l'appeler à partir d'un ViewController? D'un test unitaire où la fenêtre n'est pas encore définie? Plus de contexte serait formidable.
Houman
@Houman setRoot est une méthode d'AppDelegate qui pourrait être utilisée pour basculer entre plusieurs racines ou ParentViewController et pourrait être n'importe quelle méthode. La discussion porte sur la manière d'obtenir la référence d'AppDelegate pour un accès ultérieur, mais espérons que setRoot doit également être clair.
AiOsN
19
C'est à peu près la même chose que dans Objective-C
let del =UIApplication.sharedApplication().delegate
cela fonctionne aussi, et j'aime l'idée de la dénomination sharedInstance. Merci!
John Griffiths
2
Votre exemple instancierait toujours un nouvel AppDelegateobjet chaque fois que vous AppDelegate().sharedInstance()
appelez
1
J'aime mieux cette solution que la solution acceptée (qui est verbeuse "sans vergogne" si vous devez l'utiliser partout). Je pensais à expérimenter avec extensionpour NSApplicationavant que je trouve cette réponse, mais cela est beaucoup mieux. De nos jours, vous voudrez probablement utiliser une propriété en lecture seule calculée par classe shared, peut-être souhaitez-vous publier une mise à jour pour Swift 3?
Patru
1
Je suis en train de refactoriser mon code à utiliser, static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }ce qui est plus conforme au style Swift 3 en développement d'utiliser des propriétés en lecture seule calculées pour ce type de choses. Je pourrai probablement laisser tomber le ?une fois le refactoring terminé, vous ne pensez pas? (Désolé, le formatage du code dans les commentaires est toujours un gâchis.)
Patru
@ pxpgraphics UIApplication est une classe singleton donc pas besoin de s'inquiéter de l'instanciation multiple.
Abhijith
10
À part ce qui est dit ici, dans mon cas, j'ai raté l'importation d'UIKit:
Voici une extension UIApplicationDelegatequi évite de coder en dur le AppDelegatenom de la classe:
extensionUIApplicationDelegate{staticvar shared:Self{returnUIApplication.shared.delegate!as!Self}}// use like this:
let appDelegate =MyAppDelegate.shared // will be of type MyAppDelegate
sur le Mac pour NSApplicationDelegatecela me donne: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Est-ce obsolète?
pkamb
@pkamb Je viens de l'essayer dans un nouveau projet et je n'ai pas cette erreur. J'ai remplacé UIApplicationDelegatepar NSApplicationDelegateet UIApplicationpar NSApplication.
nyg
5
Assurez-vous import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
Dans mon cas, je manquais import UIKitau sommet de ma NSManagedObjectsous - classe. Après l'avoir importé, je pourrais supprimer cette erreur, tout comme UIApplicationla partie deUIKit
Depuis iOS 12.2 et Swift 5.0, AppDelegaten'est pas un symbole reconnu. UIApplicationDelegateest. Les réponses auxquelles il est fait référence ne AppDelegatesont donc plus correctes. La réponse suivante est correcte et évite le dépliage forcé, que certains développeurs considèrent comme une odeur de code:
Dans swift5, votre code donnera l'avertissement "UIApplication.delegate doit être utilisé uniquement à partir du thread principal". Pouvez-vous mettre à jour la réponse.
Mahesh Narla
qui fatalErrorest fonctionnellement équivalent à un déballage forcé!
pkamb
1
Dans Swift 3.0, vous pouvez obtenir la appdelegateréférence en
let appDelegate =UIApplication.shared.delegate as!AppDelegate
"crucial role"
desUIApplicationDelegate
singleton est"...to store your app’s central data objects or any content that does not have an owning view controller."
developer.apple.com/documentation/uikit/uiapplicationdelegateRéponses:
L'autre solution est correcte dans la mesure où elle vous fournira une référence au délégué de l'application, mais cela ne vous permettra pas d'accéder aux méthodes ou variables ajoutées par votre sous-classe d'UIApplication, comme votre contexte d'objet géré. Pour résoudre ce problème, il vous suffit de passer à "AppDelegate" ou à ce que votre sous-classe UIApplication soit appelée. Dans Swift 3, 4 et 5 , cela se fait comme suit:
la source
Swift 4.2
Dans Swift, facile d'accès dans vos VC
la source
Constructeurs de commodité
Swift 5
Pour utiliser la référence AppDelegate dans votre classe?
la source
C'est à peu près la même chose que dans Objective-C
la source
Cela pourrait être utilisé pour OS X
la source
let appDelegate = NSApp.delegate as AppDelegate
let appDelegate = NSApplication.shared().delegate as AppDelegate
NSApp.delegate as? AppDelegate
Voici la version Swift 2.0:
Et pour accéder au contexte de l'objet géré:
ou, en utilisant la garde:
la source
SWIFT <3
Créer une méthode dans AppDelegate Class pour ex
et l'appeler un peu ailleurs par ex
SWIFT> = 3.0
la source
AppDelegate
objet chaque fois que vousAppDelegate().sharedInstance()
extension
pourNSApplication
avant que je trouve cette réponse, mais cela est beaucoup mieux. De nos jours, vous voudrez probablement utiliser une propriété en lecture seule calculée par classeshared
, peut-être souhaitez-vous publier une mise à jour pour Swift 3?static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }
ce qui est plus conforme au style Swift 3 en développement d'utiliser des propriétés en lecture seule calculées pour ce type de choses. Je pourrai probablement laisser tomber le?
une fois le refactoring terminé, vous ne pensez pas? (Désolé, le formatage du code dans les commentaires est toujours un gâchis.)À part ce qui est dit ici, dans mon cas, j'ai raté l'importation d'UIKit:
la source
Essayez simplement ceci:
Swift 4
où dans votre AppDelegate:
la source
Voici une extension
UIApplicationDelegate
qui évite de coder en dur leAppDelegate
nom de la classe:la source
NSApplicationDelegate
cela me donne:'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?
. Est-ce obsolète?UIApplicationDelegate
parNSApplicationDelegate
etUIApplication
parNSApplication
.Assurez-vous
import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
la source
c'est très simple
Instance de délégué d'application
vous pouvez appeler une méthode avec une seule syntaxe de ligne
vous pouvez accéder à une variable avec ce code
la source
Dans mon cas, je manquais
import UIKit
au sommet de maNSManagedObject
sous - classe. Après l'avoir importé, je pourrais supprimer cette erreur, tout commeUIApplication
la partie deUIKit
J'espère que cela aide les autres !!!
la source
J'utilise ceci dans Swift 2.3.
1. dans la classe AppDelegate
2.Appelez AppDelegate avec
la source
la source
Depuis iOS 12.2 et Swift 5.0,
AppDelegate
n'est pas un symbole reconnu.UIApplicationDelegate
est. Les réponses auxquelles il est fait référence neAppDelegate
sont donc plus correctes. La réponse suivante est correcte et évite le dépliage forcé, que certains développeurs considèrent comme une odeur de code:la source
fatalError
est fonctionnellement équivalent à un déballage forcé!Dans Swift 3.0, vous pouvez obtenir la
appdelegate
référence enla source
Dans le Xcode 6.2, cela fonctionne également
la source