Zauważ, że niektórzy uznaliby użycie delegacji aplikacji jako kontenera kontekstu obiektów zarządzanych lub innych „globalnych” obiektów za anty-wzorek. Zastanów się, czy delegat aplikacji przekazuje MOC do kontrolera, zamiast sprawić, by kontroler go znalazł.
Kristopher Johnson
1
@KristopherJohnson Hej Kris, jak mogę ułatwić wprowadzanie zależności AppDelegate do kontrolerów widoku? Utwórz programowo kontroler widoku i użyj odbicia, aby zdecydować, co utworzyć / wprowadzić, rekurencyjnie? Czy są jakieś ramy, które mogą w tym pomóc? Jeśli muszę to zrobić ręcznie dla każdego kontrolera widoku, moja AppDelegate będzie ogromna! Och, najlepiej bez tworzenia fabryki wszystkiego :)
Jimbo
1
Pobieżne wyszukiwanie znalazło Swinject, który ma również automatyczne okablowanie :)
Jimbo
6
Dla programistów, którzy odradzają umieszczanie czegokolwiek „obcego” w delegacie aplikacji, to trochę nonsens, ponieważ dokumentacja Apple wyraźnie stwierdza, że jednym "crucial role"z UIApplicationDelegatesingletonów jest "...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
Odpowiedzi:
757
Drugie rozwiązanie jest poprawne, ponieważ zawiera odniesienie do delegata aplikacji, ale nie pozwoli ci uzyskać dostępu do żadnych metod lub zmiennych dodanych przez twoją podklasę UIApplication, takich jak kontekst obiektu zarządzanego. Aby rozwiązać ten problem, po prostu przejdź do „AppDelegate” lub jakkolwiek kiedykolwiek wywoływana jest twoja podklasa UIApplication. W Swift 3, 4 i 5 odbywa się to w następujący sposób:
let appDelegate =UIApplication.shared.delegate as!AppDelegatelet aVariable = appDelegate.someVariable
W przypadku, gdy ktoś nadal ma problemy, celowanie w system OS X wymaga zaimportowania kakao, aby działało to w przypadku NSApplication.sharedApplication (). Sądzę, że iOS potrzebowałby odpowiednika.
smaurice
2
Jest to bardziej przydatne z dwóch odpowiedzi.
Joe
3
@zacjordaan Za pomocą tej metody otrzymasz autouzupełnianie właściwości, ale tak naprawdę nie zadziała. W ten sposób utworzysz nową instancję klasy AppDelegate za każdym razem, gdy z niej korzystasz. Lepiej skorzystaj z delegata dostępnego przez singleton sharedApplication. A jeśli chodzi o twoje drugie pytanie, tak, prawdopodobnie chcesz użyć stałej. Chociaż możesz zmieniać właściwości AppDelegate, prawdopodobnie nie będziesz ponownie przypisywać wskaźnika do niczego innego, w którym to przypadku nie potrzebujesz zmiennej. To zależy wyłącznie od Ciebie. Rób to, co odpowiada Twoim potrzebom.
Mick MacCallum
2
Doskonała rada! Pomyślałem, że AppDelegate () jest singletonem, ale po przemyśleniu tego, co powiedziałeś, zdałem sobie sprawę, że gdyby tak było, nie byłoby wspólnego wzorca aplikacji, którego moglibyśmy używać w ten sposób. Oczywiście nie chcę odradzać niepotrzebnych instancji, jeśli nie muszę, więc twoja stała deklaracja będzie idealnie pasować; Dziękuję Ci.
zacjordaan
4
Nie chcę dodawać tego jako osobnej odpowiedzi, ale aby uzyskać AppDelegate własnymi metodami, właściwościami w projekcie, w których używane są zarówno Swift, jak i Obj-c, należy dodać #import „AppDelegate.h” do „ProjectName-BridgingHeader .h "
Byłoby wspaniale wyjaśnić, co robi setRoot () i kiedy go wywołać. np. czy można zadzwonić z ViewController? Z testu jednostkowego, w którym okno nie jest jeszcze ustawione? Większy kontekst byłby świetny.
Houman
@Houman setRoot to metoda AppDelegate, która może być używana do przełączania między wieloma Rootami lub ParentViewController i może być dowolną metodą. Dyskusja dotyczy sposobu uzyskania odniesienia do AppDelegate w celu uzyskania dalszego dostępu, ale nadzieja setRoot również musi być jasna.
AiOsN
19
Jest prawie taki sam jak w Objective-C
let del =UIApplication.sharedApplication().delegate
to również działa i podoba mi się pomysł nazewnictwa sharedInstance. dzięki!
John Griffiths,
2
Twój przykład wciąż AppDelegateAppDelegate().sharedInstance()
tworzyłby
1
Podoba mi się to rozwiązanie bardziej niż zaakceptowane (które jest „niezachwiane” pełne, jeśli musisz z niego korzystać cały czas). Myślałam o eksperymentowanie ze związkiem extensiono NSApplicationzanim znalazłem tę odpowiedź, ale jest to o wiele lepiej. W dzisiejszych czasach prawdopodobnie chciałbyś skorzystać z klasy obliczonej właściwości tylko do odczytu shared, może chcesz opublikować aktualizację do Swift 3?
Patru
1
W rzeczywistości jestem w trakcie refaktoryzacji mojego kodu, static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }który jest bardziej zgodny z rozwijającym się stylem Swift 3 polegającym na stosowaniu obliczonych właściwości tylko do odczytu dla tego typu rzeczy. Prawdopodobnie będę w stanie zrezygnować ?po zakończeniu refaktoryzacji, nie sądzisz? (Przepraszamy, formatowanie kodu w komentarzach jest zawsze bałaganem.)
Patru
@ pxpgraphics UIApplication jest klasą singletonową, więc nie musisz się martwić o wielokrotne tworzenie instancji.
Abhijith,
10
Apart z tego, co tu powiedziano, w moim przypadku przegapiłem import UIKit:
Oto rozszerzenie pozwalające UIApplicationDelegateuniknąć twardego wpisania AppDelegatenazwy klasy:
extensionUIApplicationDelegate{staticvar shared:Self{returnUIApplication.shared.delegate!as!Self}}// use like this:
let appDelegate =MyAppDelegate.shared // will be of type MyAppDelegate
na Mac za NSApplicationDelegateto daje mi: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Czy to jest przestarzałe?
pkamb
@pkamb Właśnie wypróbowałem to w nowym projekcie i nie mam tego błędu. Wymieniłem UIApplicationDelegateprzez NSApplicationDelegatei UIApplicationprzez NSApplication.
nyg
5
Upewnij się, że import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
W moim przypadku brakowało mi import UIKitna szczycie mojej NSManagedObjectpodklasy. Po zaimportowaniu mógłbym usunąć ten błąd, tak jak UIApplicationjest to w przypadkuUIKit
Począwszy od iOS 12.2 i Swift 5.0, AppDelegatenie jest rozpoznawalnym symbolem. UIApplicationDelegatejest. Wszelkie odnośne odpowiedzi AppDelegatenie są już poprawne. Poniższa odpowiedź jest poprawna i pozwala uniknąć rozpakowywania wymuszonego, które niektórzy programiści uważają za zapach kodu:
"crucial role"
zUIApplicationDelegate
singletonów jest"...to store your app’s central data objects or any content that does not have an owning view controller."
developer.apple.com/documentation/uikit/uiapplicationdelegateOdpowiedzi:
Drugie rozwiązanie jest poprawne, ponieważ zawiera odniesienie do delegata aplikacji, ale nie pozwoli ci uzyskać dostępu do żadnych metod lub zmiennych dodanych przez twoją podklasę UIApplication, takich jak kontekst obiektu zarządzanego. Aby rozwiązać ten problem, po prostu przejdź do „AppDelegate” lub jakkolwiek kiedykolwiek wywoływana jest twoja podklasa UIApplication. W Swift 3, 4 i 5 odbywa się to w następujący sposób:
źródło
Szybki 4.2
W Swift, łatwy dostęp w VC
źródło
Konstruktorzy wygody
Szybki 5
Aby użyć odwołania AppDelegate w swojej klasie?
źródło
Jest prawie taki sam jak w Objective-C
źródło
Można to wykorzystać w systemie OS X.
źródło
let appDelegate = NSApp.delegate as AppDelegate
let appDelegate = NSApplication.shared().delegate as AppDelegate
NSApp.delegate as? AppDelegate
Oto wersja Swift 2.0:
Aby uzyskać dostęp do kontekstu obiektu zarządzanego:
lub przy użyciu wartownika:
źródło
SWIFT <3
Utwórz metodę w klasie AppDelegate np
i nazwać to gdzie indziej na przykład
SWIFT> = 3,0
źródło
AppDelegate
AppDelegate().sharedInstance()
extension
oNSApplication
zanim znalazłem tę odpowiedź, ale jest to o wiele lepiej. W dzisiejszych czasach prawdopodobnie chciałbyś skorzystać z klasy obliczonej właściwości tylko do odczytushared
, może chcesz opublikować aktualizację do Swift 3?static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }
który jest bardziej zgodny z rozwijającym się stylem Swift 3 polegającym na stosowaniu obliczonych właściwości tylko do odczytu dla tego typu rzeczy. Prawdopodobnie będę w stanie zrezygnować?
po zakończeniu refaktoryzacji, nie sądzisz? (Przepraszamy, formatowanie kodu w komentarzach jest zawsze bałaganem.)Apart z tego, co tu powiedziano, w moim przypadku przegapiłem import UIKit:
źródło
Spróbuj po prostu tego:
Szybki 4
gdzie w Twojej aplikacjiDelegate:
źródło
Oto rozszerzenie pozwalające
UIApplicationDelegate
uniknąć twardego wpisaniaAppDelegate
nazwy klasy:źródło
NSApplicationDelegate
to daje mi:'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?
. Czy to jest przestarzałe?UIApplicationDelegate
przezNSApplicationDelegate
iUIApplication
przezNSApplication
.Upewnij się, że
import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
źródło
to bardzo proste
Instancja delegowania aplikacji
możesz wywołać metodę z jedną składnią wiersza
możesz uzyskać dostęp do zmiennej za pomocą tego kodu
źródło
W moim przypadku brakowało mi
import UIKit
na szczycie mojejNSManagedObject
podklasy. Po zaimportowaniu mógłbym usunąć ten błąd, tak jakUIApplication
jest to w przypadkuUIKit
Mam nadzieję, że pomaga innym !!!
źródło
Używam tego w Swift 2.3.
1. w klasie AppDelegate
2. Zadzwoń z AppDelegate za pomocą
źródło
źródło
Począwszy od iOS 12.2 i Swift 5.0,
AppDelegate
nie jest rozpoznawalnym symbolem.UIApplicationDelegate
jest. Wszelkie odnośne odpowiedziAppDelegate
nie są już poprawne. Poniższa odpowiedź jest poprawna i pozwala uniknąć rozpakowywania wymuszonego, które niektórzy programiści uważają za zapach kodu:źródło
fatalError
jest funkcjonalnym odpowiednikiem rozpakować siły!W Swift 3.0 możesz uzyskać
appdelegate
referencję przezźródło
W Xcode 6.2 to również działa
źródło