Swift'teki uygulama temsilcisine nasıl başvuru yapabilirim?


409

Swift'teki uygulama temsilcisine nasıl başvuru yapabilirim?

Sonuçta, yönetilen nesne bağlamına erişmek için başvuruyu kullanmak istiyorum.


8
Bazılarının, uygulama temsilcisinin yönetilen nesne bağlamı veya diğer "genel" nesnelerin bir anti-desen olması için bir kapsayıcı olarak kullanacağını unutmayın. Uygulama temsilcisinin denetleyiciyi bulmasını sağlamak yerine MOC'yi denetleyiciye geçirmesini sağlayın.
Kristopher Johnson

1
@ KristopherJohnson Hey Kris, AppDelegate'in görünüm denetleyicilerine bağımlılık eklemesini nasıl kolaylaştırabilirim? Görünüm denetleyicisini programlı olarak başlatın ve nükseden / enjekte edeceğinize özyinelemede karar vermek için yansımayı kullanın? Bu konuda yardımcı olabilecek çerçeveler var mı? Bunu her görünüm denetleyicisi için manuel olarak yapmam gerekirse, AppDelegate'im çok büyük olacak! Oh, tercihen her şey için bir fabrika yaratmadan :)
Jimbo

1
Lanetli bir arama bulundu , ayrıca otomatik kablolama var Swinject :)
Jimbo

6
Elma belgeler açıkça belirtmektedir çünkü uygulama temsilci "yabancı" bir şey koyarak karşı tavsiye programcılar için, biraz saçma "crucial role"bir UIApplicationDelegatetekil olan "...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

Yanıtlar:


757

Diğer çözüm, uygulamanın temsilcisine bir referans alması açısından doğrudur, ancak bu, yönetilen nesne bağlamınız gibi UIApplication alt sınıfınız tarafından eklenen yöntemlere veya değişkenlere erişmenize izin vermez. Bu sorunu çözmek için, "AppDelegate" e veya UIApplication alt sınıfınızın çağrılması için basit bir şekilde sürün. Gelen Swift 3, 4 ve 5 , aşağıdaki gibi yapılır:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let aVariable = appDelegate.someVariable

10
Birisi hala sorun yaşıyorsa, OS X'i hedeflemek, bunun NSApplication.sharedApplication () için çalışması için Cocoa'yı içe aktarmanızı gerektirir. İOS'un eşdeğeri olması gerektiğini tahmin ediyorum.
smaurice

2
Bu iki cevaptan daha faydalıdır.
Joe

3
@zacjordaan Bu yöntemi kullanarak, özellik için otomatik tamamlama elde edersiniz, ancak aslında çalışmaz. Bu şekilde, her kullandığınızda AppDelegate sınıfının yeni bir örneğini oluşturur. SharedApplication singletonundan erişilebilen temsilciyi kullanmanız daha iyi olur. İkinci sorunuza gelince, evet muhtemelen bir sabit kullanmak istiyorsunuz. AppDelegate'in özelliklerini değiştiriyor olsanız bile, muhtemelen işaretçiyi başka bir şeye yeniden atamayacaksınız, bu durumda bir değişkene gerek yoktur. Bu tamamen size kalmış. İhtiyacınıza uygun olanı yapın.
Mick MacCallum

2
Mükemmel tavsiye! Yanlışlıkla AppDelegate () 'in singleton olduğunu düşündüm, ancak söylediklerinizi düşündükten sonra, o zaman bu şekilde kullanmamız için paylaşılan bir Uygulama deseni olmayacağını anladım. Tabii ki, gerekmediğim takdirde gereksiz örnekleri ortaya çıkarmak istemiyorum, bu yüzden sürekli beyanınız mükemmel bir şekilde uygun olacak; Teşekkür ederim.
zacjordaan

4
Bunu ayrı bir cevap olarak eklemek istemiyorum, ancak AppDelegate'i kendi yöntemlerinizle, hem Swift hem de Obj-c'nin kullanıldığı projedeki özellikleri almak için "ProjectName-BridgingHeader'a #import" AppDelegate.h "eklemelisiniz. .h "
Marcin Mierzejewski

44

Hızlı 4.2

Swift'te, VC'lerinize kolayca erişebilirsiniz

extension UIViewController {
    var appDelegate: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
   }
}

26

Kullanışlı Yapıcılar

Kodun sonuna AppDelegate Sınıfına ekleyin

Hızlı 5

func appDelegate() -> AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}

AppDelegate referansını sınıfınızda kullanmak için?


AppDelegate Yöntemini Arayın

AppDelegate (). setRoot ()


SetRoot () 'un ne yaptığını ve ne zaman çağrılacağını açıklamak harika olurdu. örneğin bir ViewController den çağırmak için uygun mu? Birim testinden pencere henüz ayarlanmadı mı? Daha fazla bağlam harika olurdu.
Houman

@Houman setRoot, birden fazla Kök veya ParentViewController arasında geçiş yapmak için kullanılabilen ve herhangi bir yöntem olabilecek AppDelegate'in yöntemidir. Tartışma, AppDelegate'in daha fazla erişime nasıl başvurulacağıyla ilgilidir, ancak setRoot'un da net olması gerektiğini umuyoruz.
AiOsN

19

Objective-C ile hemen hemen aynı

let del = UIApplication.sharedApplication().delegate

19

Bu OS X için kullanılabilir

let appDelegate = NSApplication.sharedApplication().delegate as AppDelegate
var managedObjectContext = appDelegate.managedObjectContext?

3
Veya basitçelet appDelegate = NSApp.delegate as AppDelegate
Vladimir Prudnikov

1
In Swift 3 kullanımlet appDelegate = NSApplication.shared().delegate as AppDelegate
Dirk

4
In Swift 4 :NSApp.delegate as? AppDelegate
Nick

12

İşte Swift 2.0 sürümü:

let delegate = UIApplication.sharedApplication().delegate as? AppDelegate

Ve yönetilen nesne içeriğine erişmek için:

    if let delegate = UIApplication.sharedApplication().delegate as? AppDelegate {

        let moc = delegate.managedObjectContext

        // your code here

    }

veya koruma kullanarak:

    guard let delegate = UIApplication.sharedApplication().delegate as? AppDelegate  else {
        return
    }

    let moc = delegate.managedObjectContext

    // your code here

10

SWIFT <3

AppDelegate Sınıfında ex için yöntem oluşturma

func sharedInstance() -> AppDelegate{
        return UIApplication.sharedApplication().delegate as! AppDelegate
    }

ve bunu eski yerlere

let appDelegate : AppDelegate = AppDelegate().sharedInstance()

SWIFT> = 3.0

func sharedInstance() -> AppDelegate{
    return UIApplication.shared.delegate as! AppDelegate
}

2
Bu da işe yarıyor ve sharedInstance adlandırma fikrini seviyorum. Teşekkürler!
John Griffiths

2
AppDelegateAppDelegate().sharedInstance()
Örneğiniz,

1
Bu çözümü kabul edilenlerden daha iyi seviyorum (her şeyi kullanmanız gerekiyorsa "kazara" ayrıntılı). Ben bu cevabı bulmadan önce bir extensionfor ile deneme yapmayı düşünüyordum NSApplication, ama bu çok daha iyi. Günümüzde muhtemelen bir sınıf bilgisayarlı salt okunur özelliği kullanmak istersinizshared , belki Swift 3 için bir güncelleme göndermek ister misiniz?
Patru

1
Aslında static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }bu tür şeyler için hesaplanmış salt okunur özellikleri kullanarak gelişen Swift 3 tarzı daha uyumlu kullanmak için kodumu yeniden düzenleme sürecinde . ?Yeniden düzenleme tamamlandıktan sonra muhtemelen bırakabilirim, değil mi? (Üzgünüm, yorumlarda kod biçimlendirme her zaman karışıklıktır.)
Patru

@ pxpgraphics UIApplication tek bir sınıftır, bu nedenle birden fazla örnekleme konusunda endişelenmenize gerek yoktur.
Abhijith


6

Sadece şunu deneyin:

Hızlı 4

// Call the method
(UIApplication.shared.delegate as? AppDelegate)?.whateverWillOccur()

AppDelegate'inizde:

// MARK: - Whatever
func whateverWillOccur() {

    // Your code here.

}

5

Sınıf isminin UIApplicationDelegatekodlanmasını önlemek için bir uzantı AppDelegate:

extension UIApplicationDelegate {

    static var shared: Self {    
        return UIApplication.shared.delegate! as! Self
    }
}

// use like this:
let appDelegate = MyAppDelegate.shared // will be of type MyAppDelegate

için Mac üzerinde NSApplicationDelegatebu bana verir: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Bu modası geçmiş mi?
pkamb

@pkamb Yeni bir projede denedim ve bu hatayla karşılaşmadım. Ben yerini UIApplicationDelegatetarafından NSApplicationDelegateve UIApplicationtarafından NSApplication.
nyg

5
  1. Emin olun import UIKit

  2. let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate


4

o çok basit

Uygulama temsilci örneği

let app = UIApplication.shared.delegate as! AppDelegate

tek satır sözdizimiyle bir yöntemi çağırabilirsiniz

app.callingMethod()

bu kodla bir değişkene erişebilirsiniz

app.yourVariable = "Assigning a value"

2

Benim durumumda, alt sınıfımın import UIKitüstünde eksikti NSManagedObject. Olarak içe aktardıktan sonra, o hatayı kaldırmak olabilir UIApplicationparçasıdırUIKit

Umarım başkalarına yardımcı olur !!!


2

Bunu Swift 2.3'te kullanıyorum.

1. AppDelegate sınıfında

static let sharedInstance: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

2. AppDelegate ile ara

let appDelegate = AppDelegate.sharedInstance

2
extension AppDelegate {

    // MARK: - App Delegate Ref
    class func delegate() -> AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
}

2

İOS 12.2 ve Swift 5.0'dan itibaren AppDelegatetanınan bir sembol değildir. UIApplicationDelegatedır-dir. Bu AppDelegatenedenle atıfta bulunulan yanıtlar artık doğru değil. Aşağıdaki cevap doğrudur ve bazı geliştiricilerin kod kokusu olarak gördüğü zorla açmayı önler:

import UIKit

extension UIViewController {
  var appDelegate: UIApplicationDelegate {
    guard let appDelegate = UIApplication.shared.delegate else {
      fatalError("Could not determine appDelegate.")
    }
    return appDelegate
  }
}

1
Swift5 içinde kodunuz "UIApplication.delegate yalnızca ana iş parçacığından kullanılmalıdır" uyarısı verecektir. Cevabı güncelleyebilir misiniz?
Mahesh Narla

O fatalErrorbir kuvvet paketini işlevsel eşdeğerdir!
pkamb

1

Swift 3.0'da appdelegatereferansı şu adresten alabilirsiniz :

let appDelegate = UIApplication.shared.delegate as! AppDelegate

0

Xcode 6.2'de bu da işe yarıyor

let appDelegate = UIApplication.sharedApplication().delegate! as AppDelegate

let aVariable = appDelegate.someVariable

2
v01d, bunu nereden aldın?
NSPratik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.