Perhatikan bahwa beberapa orang akan menganggap penggunaan delegasi aplikasi sebagai wadah untuk konteks objek yang dikelola atau objek "global" lainnya sebagai anti-pola. Pertimbangkan meminta delegasi aplikasi meneruskan MOC ke controller, daripada membuat controller menemukannya.
Kristopher Johnson
1
@KristopherJohnson Hei Kris, bagaimana saya bisa memfasilitasi ketergantungan AppDelegate menyuntikkan ke pengontrol tampilan? Instantiate tampilan controller secara terprogram dan gunakan refleksi untuk memutuskan apa yang akan instantiate / menyuntikkan, secara rekursif? Apakah ada kerangka kerja yang dapat membantu dengan ini? Jika saya harus melakukan ini untuk setiap pengontrol tampilan secara manual, AppDelegate saya akan menjadi sangat besar! Oh, lebih baik tanpa membuat pabrik untuk semuanya :)
Jimbo
1
Pencarian sepintas menemukan Swinject yang juga memiliki auto-wiring :)
Jimbo
6
Untuk programmer yang menyarankan untuk tidak memasukkan sesuatu yang "asing" dalam delegasi aplikasi, itu sedikit omong kosong karena dokumentasi Apple secara eksplisit menyatakan bahwa salah "crucial role"satu UIApplicationDelegatesingleton adalah "...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
Jawaban:
757
Solusi lain benar karena akan memberi Anda referensi ke delegasi aplikasi, tetapi ini tidak akan memungkinkan Anda untuk mengakses metode atau variabel apa pun yang ditambahkan oleh subkelas aplikasi UIA, seperti konteks objek terkelola. Untuk mengatasinya, cukup turunkan ke "AppDelegate" atau apa pun subkelas aplikasi UIA Anda yang dipanggil. Dalam Swift 3, 4 & 5 , ini dilakukan sebagai berikut:
let appDelegate =UIApplication.shared.delegate as!AppDelegatelet aVariable = appDelegate.someVariable
Jika ada yang masih mengalami masalah, penargetan OS X mengharuskan Anda untuk mengimpor Kakao agar ini berfungsi untuk NSApplication. SharedApplication (). Saya kira iOS akan membutuhkan yang setara.
smaurice
2
Ini lebih berguna dari dua jawaban.
Joe
3
@zacjordaan Menggunakan metode itu, Anda akan mendapatkan pelengkapan otomatis untuk properti, tetapi itu tidak akan benar-benar berfungsi. Dengan begitu akan membuat instance baru dari kelas AppDelegate setiap kali Anda menggunakannya. Anda lebih baik menggunakan delegasi yang dapat diakses melalui singleton Aplikasi bersama. Dan sejauh pertanyaan kedua Anda, ya, Anda mungkin ingin menggunakan konstanta. Meskipun, Anda mungkin mengubah properti AppDelegate, Anda mungkin tidak akan menetapkan ulang pointer ke hal lain, dalam hal ini, tidak perlu variabel. Ini sepenuhnya terserah Anda sekalipun. Lakukan apa yang sesuai dengan kebutuhan Anda.
Mick MacCallum
2
Saran yang sangat baik! Saya keliru mengira bahwa AppDelegate () adalah singleton tetapi setelah memikirkan apa yang Anda katakan, saya menyadari bahwa jika itu terjadi maka tidak akan ada pola Aplikasi bersama untuk kita gunakan dengan cara ini. Tentu saja saya tidak ingin menelurkan contoh yang tidak perlu jika saya tidak perlu, sehingga deklarasi konstan Anda akan cocok dengan sempurna; Terima kasih.
zacjordaan
4
Saya tidak ingin menambahkan ini sebagai jawaban terpisah, tetapi untuk mendapatkan AppDelegate dengan metode Anda sendiri, properti di proyek tempat Swift dan Obj-c digunakan. Anda harus menambahkan #import "AppDelegate.h" ke "ProjectName-BridgingHeader .h "
Akan bagus untuk menjelaskan apa yang dilakukan setRoot () dan kapan harus memanggilnya. misalnya apakah boleh memanggilnya dari ViewController? Dari tes Unit di mana jendela belum diatur? Lebih banyak konteks akan lebih bagus.
Houman
@Houman setRoot adalah metode dari AppDelegate yang dapat digunakan untuk beralih di antara banyak Roots atau ParentViewController dan bisa berupa metode apa pun. Diskusi adalah tentang cara mendapatkan referensi AppDelegate untuk akses lebih lanjut, tetapi berharap setRoot juga harus jelas.
AiOsN
19
Ini hampir sama dengan di Objective-C
let del =UIApplication.sharedApplication().delegate
ini juga berfungsi, dan saya suka gagasan penamaan sharedInstance. Terima kasih!
John Griffiths
2
Contoh Anda masih akan instantiate AppDelegateobjek baru setiap kali Anda meneleponAppDelegate().sharedInstance()
pxpgraphics
1
Saya suka solusi ini lebih baik daripada yang diterima (yang "unsiwftly" verbose jika Anda harus menggunakannya di seluruh). Saya sedang berpikir tentang bereksperimen dengan extensionuntuk NSApplicationsebelum saya menemukan jawaban ini, tetapi ini jauh lebih baik. Namun saat ini Anda mungkin ingin menggunakan properti read only yang dikomputasi dengan kelas shared, mungkin Anda ingin memposting pembaruan untuk Swift 3?
Patru
1
Saya sebenarnya dalam proses refactoring kode saya untuk menggunakan static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }yang lebih sejalan dengan pengembangan gaya Swift 3 menggunakan properti read only untuk jenis hal-hal ini. Saya mungkin akan bisa drop ?setelah refactoring selesai, bukan begitu? (Maaf, pemformatan kode dalam komentar selalu berantakan.)
Patru
@ pxpgraphics UIApplication adalah kelas tunggal sehingga tidak perlu khawatir tentang banyak instance.
Abhijith
10
Appart dari apa yang diceritakan di sini, dalam kasus saya, saya melewatkan impor UIKit:
Berikut ini ekstensi untuk UIApplicationDelegateyang menghindari pengodean AppDelegatenama kelas:
extensionUIApplicationDelegate{staticvar shared:Self{returnUIApplication.shared.delegate!as!Self}}// use like this:
let appDelegate =MyAppDelegate.shared // will be of type MyAppDelegate
pada Mac untuk NSApplicationDelegateini memberi saya: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Apakah ini ketinggalan jaman?
pkamb
@ pkamb Saya baru saja mencobanya di proyek baru dan saya tidak memiliki kesalahan ini. Saya digantikan UIApplicationDelegateoleh NSApplicationDelegatedan UIApplicationoleh NSApplication.
Nyg
5
Pastikan Anda import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
Dalam kasus saya, saya hilang import UIKitdi atas NSManagedObjectsubkelas saya . Setelah mengimpornya, saya bisa menghapus kesalahan itu sebagaimana UIApplicationbagian dariUIKit
Pada iOS 12.2 dan Swift 5.0, AppDelegatebukan simbol yang dikenali. UIApplicationDelegateadalah. AppDelegateKarenanya, jawaban yang merujuk tidak lagi benar. Jawaban berikut ini benar dan menghindari pembatalan paksa, yang oleh beberapa pengembang dianggap sebagai bau kode:
"crucial role"
satuUIApplicationDelegate
singleton adalah"...to store your app’s central data objects or any content that does not have an owning view controller."
developer.apple.com/documentation/uikit/uiapplicationdelegateJawaban:
Solusi lain benar karena akan memberi Anda referensi ke delegasi aplikasi, tetapi ini tidak akan memungkinkan Anda untuk mengakses metode atau variabel apa pun yang ditambahkan oleh subkelas aplikasi UIA, seperti konteks objek terkelola. Untuk mengatasinya, cukup turunkan ke "AppDelegate" atau apa pun subkelas aplikasi UIA Anda yang dipanggil. Dalam Swift 3, 4 & 5 , ini dilakukan sebagai berikut:
sumber
Cepat 4.2
Di Swift, mudah diakses di VC Anda
sumber
Konstruktor Kenyamanan
Cepat 5
Untuk menggunakan referensi AppDelegate di kelas Anda?
sumber
Ini hampir sama dengan di Objective-C
sumber
Ini dapat digunakan untuk OS X
sumber
let appDelegate = NSApp.delegate as AppDelegate
let appDelegate = NSApplication.shared().delegate as AppDelegate
NSApp.delegate as? AppDelegate
Berikut adalah versi Swift 2.0:
Dan untuk mengakses konteks objek yang dikelola:
atau, menggunakan pelindung:
sumber
SWIFT <3
Buat metode di Kelas AppDelegate untuk ex
dan menyebutnya beberapa tempat lain untuk mantan
SWIFT> = 3.0
sumber
AppDelegate
objek baru setiap kali Anda meneleponAppDelegate().sharedInstance()
extension
untukNSApplication
sebelum saya menemukan jawaban ini, tetapi ini jauh lebih baik. Namun saat ini Anda mungkin ingin menggunakan properti read only yang dikomputasi dengan kelasshared
, mungkin Anda ingin memposting pembaruan untuk Swift 3?static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }
yang lebih sejalan dengan pengembangan gaya Swift 3 menggunakan properti read only untuk jenis hal-hal ini. Saya mungkin akan bisa drop?
setelah refactoring selesai, bukan begitu? (Maaf, pemformatan kode dalam komentar selalu berantakan.)Appart dari apa yang diceritakan di sini, dalam kasus saya, saya melewatkan impor UIKit:
sumber
Coba ini saja:
Cepat 4
di mana di AppDelegate Anda:
sumber
Berikut ini ekstensi untuk
UIApplicationDelegate
yang menghindari pengodeanAppDelegate
nama kelas:sumber
NSApplicationDelegate
ini memberi saya:'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?
. Apakah ini ketinggalan jaman?UIApplicationDelegate
olehNSApplicationDelegate
danUIApplication
olehNSApplication
.Pastikan Anda
import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
sumber
ini sangat sederhana
Contoh delegasi aplikasi
Anda dapat memanggil metode dengan sintaksis satu baris
Anda dapat mengakses variabel dengan kode ini
sumber
Dalam kasus saya, saya hilang
import UIKit
di atasNSManagedObject
subkelas saya . Setelah mengimpornya, saya bisa menghapus kesalahan itu sebagaimanaUIApplication
bagian dariUIKit
Semoga ini bisa membantu orang lain !!!
sumber
Saya menggunakan ini di Swift 2.3.
1. di kelas AppDelegate
2. Hubungi AppDelegate dengan
sumber
sumber
Pada iOS 12.2 dan Swift 5.0,
AppDelegate
bukan simbol yang dikenali.UIApplicationDelegate
adalah.AppDelegate
Karenanya, jawaban yang merujuk tidak lagi benar. Jawaban berikut ini benar dan menghindari pembatalan paksa, yang oleh beberapa pengembang dianggap sebagai bau kode:sumber
fatalError
secara fungsional setara dengan kekuatan yang terbuka!Di Swift 3.0 Anda bisa mendapatkan
appdelegate
referensi dengansumber
Dalam Xcode 6.2, ini juga berfungsi
sumber