Beachten Sie, dass einige die Verwendung des App-Delegaten als Container für den verwalteten Objektkontext oder andere "globale" Objekte als Anti-Pattern betrachten würden. Lassen Sie den App-Delegaten den MOC an den Controller übergeben, anstatt ihn vom Controller finden zu lassen.
Kristopher Johnson
1
@KristopherJohnson Hey Kris, wie kann ich das Einfügen von Abhängigkeiten in Ansichtscontroller durch AppDelegate vereinfachen? Instanziieren Sie den View Controller programmgesteuert und verwenden Sie die Reflexion, um zu entscheiden, was rekursiv instanziiert / injiziert werden soll. Gibt es Frameworks, die dabei helfen können? Wenn ich dies für jeden View Controller manuell tun muss, wird mein AppDelegate riesig! Oh, am besten ohne eine Fabrik für alles zu schaffen :)
Jimbo
1
Eine flüchtige Suche fand Swinject, das auch automatische Verkabelung hat :)
Jimbo
6
Für Programmierer , die gegen Putting etwas „fremden“ in der App Delegierten beraten, ist es ein Unsinn Bit , weil der Apple - Dokumentation ausdrücklich , dass eine "crucial role"der UIApplicationDelegateSingleton ist "...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
Antworten:
756
Die andere Lösung ist insofern korrekt, als Sie einen Verweis auf den Delegaten der Anwendung erhalten. Auf diese Weise können Sie jedoch nicht auf Methoden oder Variablen zugreifen, die von Ihrer UIApplication-Unterklasse hinzugefügt wurden, wie z. B. Ihren verwalteten Objektkontext. Um dies zu beheben, senden Sie einfach einen Downcast auf "AppDelegate" oder wie auch immer Ihre UIApplication-Unterklasse aufgerufen wird. In Swift 3, 4 & 5 wird dies wie folgt durchgeführt:
let appDelegate =UIApplication.shared.delegate as!AppDelegatelet aVariable = appDelegate.someVariable
Falls immer noch Probleme auftreten, müssen Sie für das Targeting von OS X Cocoa importieren, damit dies für NSApplication.sharedApplication () funktioniert. Ich würde vermuten, dass iOS das Äquivalent benötigen würde.
Smaurice
2
Dies ist die nützlichere der beiden Antworten.
Joe
3
@zacjordaan Mit dieser Methode erhalten Sie eine automatische Vervollständigung für die Eigenschaft, die jedoch nicht funktioniert. Auf diese Weise wird bei jeder Verwendung eine neue Instanz der AppDelegate-Klasse erstellt. Verwenden Sie besser den Delegaten, auf den Sie über den Singleton "sharedApplication" zugreifen können. Und was Ihre zweite Frage betrifft, möchten Sie wahrscheinlich eine Konstante verwenden. Auch wenn Sie möglicherweise die Eigenschaften von AppDelegate ändern, werden Sie den Zeiger wahrscheinlich nicht neu zuweisen. In diesem Fall ist keine Variable erforderlich. Dies liegt jedoch ganz bei Ihnen. Tun Sie, was Ihren Bedürfnissen entspricht.
Mick MacCallum
2
Exzellenter Rat! Ich hatte fälschlicherweise gedacht, dass AppDelegate () Singleton ist, aber nachdem ich über das nachgedacht habe, was Sie gesagt haben, habe ich festgestellt, dass es in diesem Fall kein SharedApplication-Muster geben würde, das wir auf diese Weise verwenden könnten. Natürlich möchte ich keine unnötigen Instanzen erzeugen, wenn ich nicht muss, daher wird Ihre ständige Erklärung perfekt passen. Vielen Dank.
Zacjordaan
4
Ich möchte dies nicht als separate Antwort hinzufügen, aber um AppDelegate mit Ihren eigenen Methoden und Eigenschaften in einem Projekt zu erhalten, in dem sowohl ein Swift als auch ein Obj-c verwendet werden, sollten Sie #import "AppDelegate.h" zu "ProjectName-BridgingHeader" hinzufügen .h "
Es wäre toll zu erklären, was setRoot () macht und wann es aufgerufen werden soll. Ist es beispielsweise in Ordnung, es von einem ViewController aus aufzurufen? Aus einem Unit-Test, bei dem das Fenster noch nicht eingestellt ist? Mehr Kontext wäre toll.
Houman
@Houman setRoot ist eine Methode von AppDelegate, mit der zwischen mehreren Roots oder ParentViewController gewechselt werden kann und die eine beliebige Methode sein kann. In der Diskussion geht es darum, wie die Referenz von AppDelegate für den weiteren Zugriff verwendet werden kann, aber hoffentlich muss auch setRoot klar sein.
AiOsN
19
Es ist so ziemlich das gleiche wie in Objective-C
let del =UIApplication.sharedApplication().delegate
Dies funktioniert auch und ich mag die Idee der SharedInstance-Benennung. Vielen Dank!
John Griffiths
2
Ihr Beispiel würde immer noch ein neues AppDelegateObjekt instanziieren, wenn Sie AppDelegate().sharedInstance()
anrufen
1
Ich mag diese Lösung besser als die akzeptierte (die "unsiwftly" ausführlich ist, wenn Sie sie überall verwenden müssen). Ich habe darüber nachgedacht, mit einem extensionfor zu experimentieren, NSApplicationbevor ich diese Antwort gefunden habe, aber das ist viel besser. Heutzutage möchten Sie wahrscheinlich eine klassenberechnete schreibgeschützte Eigenschaft verwenden shared. Vielleicht möchten Sie ein Update für Swift 3 veröffentlichen?
Patru
1
Ich bin gerade dabei, meinen Code für die Verwendung umzugestalten, static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }was eher dem sich entwickelnden Swift 3-Stil entspricht, berechnete schreibgeschützte Eigenschaften für diese Art von Dingen zu verwenden. Ich werde das wahrscheinlich fallen lassen können, ?sobald das Refactoring abgeschlossen ist, meinst du nicht auch? (Sorry, Code-Formatierung in Kommentaren ist immer ein Chaos.)
Patru
@ pxpgraphics UIApplication ist eine Singleton-Klasse, sodass Sie sich keine Gedanken über die mehrfache Instanziierung machen müssen.
Abhijith
10
Abgesehen von dem, was hier gesagt wird, habe ich in meinem Fall den Import von UIKit verpasst:
Hier ist eine Erweiterung UIApplicationDelegate, die das Hardcodieren des AppDelegateKlassennamens vermeidet :
extensionUIApplicationDelegate{staticvar shared:Self{returnUIApplication.shared.delegate!as!Self}}// use like this:
let appDelegate =MyAppDelegate.shared // will be of type MyAppDelegate
auf dem Mac NSApplicationDelegatedafür gibt mir : 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Ist das veraltet?
Pkamb
@pkamb Ich habe es gerade in einem neuen Projekt versucht und ich habe diesen Fehler nicht. Ich habe UIApplicationDelegatenach NSApplicationDelegateund UIApplicationnach ersetzt NSApplication.
Nyg
5
Stell sicher, dass du import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
In meinem Fall fehlte ich import UIKitoben in meiner NSManagedObjectUnterklasse. Nach dem Import konnte ich diesen Fehler wie UIApplicationder Teil von entfernenUIKit
Ab iOS 12.2 und Swift 5.0 AppDelegateist kein Symbol anerkannt. UIApplicationDelegateist. Alle Antworten, auf die Bezug genommen wird, AppDelegatesind daher nicht mehr korrekt. Die folgende Antwort ist richtig und vermeidet das gewaltsame Auspacken, das einige Entwickler als Codegeruch betrachten:
"crucial role"
derUIApplicationDelegate
Singleton ist"...to store your app’s central data objects or any content that does not have an owning view controller."
developer.apple.com/documentation/uikit/uiapplicationdelegateAntworten:
Die andere Lösung ist insofern korrekt, als Sie einen Verweis auf den Delegaten der Anwendung erhalten. Auf diese Weise können Sie jedoch nicht auf Methoden oder Variablen zugreifen, die von Ihrer UIApplication-Unterklasse hinzugefügt wurden, wie z. B. Ihren verwalteten Objektkontext. Um dies zu beheben, senden Sie einfach einen Downcast auf "AppDelegate" oder wie auch immer Ihre UIApplication-Unterklasse aufgerufen wird. In Swift 3, 4 & 5 wird dies wie folgt durchgeführt:
quelle
Swift 4.2
In Swift einfach in Ihren VCs zuzugreifen
quelle
Convenience-Konstruktoren
Swift 5
So verwenden Sie die AppDelegate-Referenz in Ihrer Klasse?
quelle
Es ist so ziemlich das gleiche wie in Objective-C
quelle
Dies könnte für OS X verwendet werden
quelle
let appDelegate = NSApp.delegate as AppDelegate
let appDelegate = NSApplication.shared().delegate as AppDelegate
NSApp.delegate as? AppDelegate
Hier ist die Swift 2.0-Version:
Und um auf den Kontext des verwalteten Objekts zuzugreifen:
oder mit Wache:
quelle
SWIFT <3
Erstellen Sie beispielsweise eine Methode in der AppDelegate-Klasse
und nenne es woanders zum Beispiel
SWIFT> = 3.0
quelle
AppDelegate
Objekt instanziieren, wenn SieAppDelegate().sharedInstance()
extension
for zu experimentieren,NSApplication
bevor ich diese Antwort gefunden habe, aber das ist viel besser. Heutzutage möchten Sie wahrscheinlich eine klassenberechnete schreibgeschützte Eigenschaft verwendenshared
. Vielleicht möchten Sie ein Update für Swift 3 veröffentlichen?static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }
was eher dem sich entwickelnden Swift 3-Stil entspricht, berechnete schreibgeschützte Eigenschaften für diese Art von Dingen zu verwenden. Ich werde das wahrscheinlich fallen lassen können,?
sobald das Refactoring abgeschlossen ist, meinst du nicht auch? (Sorry, Code-Formatierung in Kommentaren ist immer ein Chaos.)Abgesehen von dem, was hier gesagt wird, habe ich in meinem Fall den Import von UIKit verpasst:
quelle
Versuchen Sie einfach Folgendes:
Swift 4
Wo in Ihrem AppDelegate:
quelle
Hier ist eine Erweiterung
UIApplicationDelegate
, die das Hardcodieren desAppDelegate
Klassennamens vermeidet :quelle
NSApplicationDelegate
dafür gibt mir :'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?
. Ist das veraltet?UIApplicationDelegate
nachNSApplicationDelegate
undUIApplication
nach ersetztNSApplication
.Stell sicher, dass du
import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
quelle
es ist sehr einfach
App-Delegateninstanz
Sie können eine Methode mit einzeiliger Syntax aufrufen
Mit diesem Code können Sie auf eine Variable zugreifen
quelle
In meinem Fall fehlte ich
import UIKit
oben in meinerNSManagedObject
Unterklasse. Nach dem Import konnte ich diesen Fehler wieUIApplication
der Teil von entfernenUIKit
Hoffe es hilft anderen !!!
quelle
Ich benutze dies in Swift 2.3.
1.in AppDelegate-Klasse
2. Rufen Sie AppDelegate mit an
quelle
quelle
Ab iOS 12.2 und Swift 5.0
AppDelegate
ist kein Symbol anerkannt.UIApplicationDelegate
ist. Alle Antworten, auf die Bezug genommen wird,AppDelegate
sind daher nicht mehr korrekt. Die folgende Antwort ist richtig und vermeidet das gewaltsame Auspacken, das einige Entwickler als Codegeruch betrachten:quelle
fatalError
entspricht funktional einer Kraft zum Auspacken!In Swift 3.0 können Sie die
appdelegate
Referenz von erhaltenquelle
Im Xcode 6.2 funktioniert dies auch
quelle