Swiftでアプリデリゲートへの参照を取得するにはどうすればよいですか?


409

Swiftでアプリデリゲートへの参照を取得するにはどうすればよいですか?

最終的には、参照を使用して管理対象オブジェクトのコンテキストにアクセスしたいと思います。


8
管理者オブジェクトコンテキストまたは他の「グローバル」オブジェクトのコンテナーとしてのアプリデリゲートの使用をアンチパターンと見なす人もいることに注意してください。コントローラーにMOCを見つけさせるのではなく、アプリデリゲートにMOCをコントローラーに渡すことを検討してください。
クリストファージョンソン2014

1
@KristopherJohnson Hey Kris、AppDelegateが依存関係をView Controllerに注入するのをどのように促進できますか?プログラムでビューコントローラーをインスタンス化し、リフレクションを使用して、再帰的にインスタンス化/注入するものを決定しますか?これに役立つフレームワークはありますか?すべてのビューコントローラーに対して手動でこれを行う必要がある場合、私のAppDelegateは巨大になります!ああ、できればすべてのファクトリを作成しないでください:)
Jimbo

1
大まかな検索の結果、自動配線もあるSwinjectが見つかりました:)
神保

6
アプリのデリゲートに「余分な」ものを入れないようにアドバイスするプログラマーにとって"crucial role"UIApplicationDelegateシングルトンの1つは"...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

回答:


757

他の解決策は、アプリケーションのデリゲートへの参照を取得するという点で正しいですが、これにより、管理対象オブジェクトのコンテキストなど、UIApplicationのサブクラスによって追加されたメソッドや変数にアクセスできなくなります。これを解決するには、単に「AppDelegate」にダウンキャストするか、UIApplicationサブクラスが呼び出された場合に何が呼び出されるかを確認します。でスウィフト3、4および5次のように、これが行われます。

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

10
それでも問題が発生する場合は、OS Xをターゲットにするには、NSApplication.sharedApplication()で動作するようにCocoaをインポートする必要があります。iOSには同等の機能が必要だと思います。
smaurice 14年

2
これは、2つの答えのうち、より有用です。
ジョー

3
@zacjordaanそのメソッドを使用すると、プロパティのオートコンプリートが取得されますが、実際には機能しません。これにより、使用するたびにAppDelegateクラスの新しいインスタンスが作成されます。sharedApplicationシングルトンを介してアクセス可能なデリゲートを使用するほうがよいでしょう。そして、2番目の質問に関する限り、はい、おそらく定数を使用したいでしょう。AppDelegateのプロパティを変更している場合でも、おそらくポインターを他のものに再割り当てすることはありません。その場合、変数は必要ありません。これは完全にあなた次第です。あなたのニーズに合ったことをしてください。
Mick MacCallum 2014年

2
素晴らしいアドバイス!AppDelegate()はシングルトンであると誤って考えていましたが、あなたが言ったことを考えた後、この方法で使用するためのsharedApplicationパターンはないことに気付きました。もちろん、必要がない場合に不要なインスタンスを生成したくないので、定数宣言は完全に適合します。ありがとうございました。
zacjordaan 2014年

4
これを個別の回答として追加したくありませんが、独自のメソッドでAppDelegateを取得するには、SwiftとObj-cの両方が使用されているプロジェクトのプロパティを使用します。#import "AppDelegate.h"を "ProjectName-BridgingHeader"に追加する必要があります.h "
Marcin Mierzejewski

44

Swift 4.2

Swiftでは、VCで簡単にアクセスできます

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

26

便利なコンストラクタ

コードの最後にAppDelegateクラスを追加する

スウィフト5

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

クラスでAppDelegate参照を使用するには?


AppDelegateメソッドを呼び出す

appDelegate()。setRoot()


setRoot()が何をするか、いつそれを呼び出すかを説明するのに最適でしょう。たとえば、ViewControllerから呼び出すことはできますか?ウィンドウがまだ設定されていない単体テストから?より多くのコンテキストが素晴らしいでしょう。
Houman

@Houman setRootはAppDelegateのメソッドであり、複数のRootまたはParentViewControllerを切り替えるために使用でき、どのメソッドでもかまいません。議論はAppDelegateの参照をさらにアクセスする方法についてですが、setRootも明確でなければならないことを願っています。
AiOsN

19

Objective-Cとほとんど同じです

let del = UIApplication.sharedApplication().delegate

19

これはOS Xに使用できます

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

3
または単にlet appDelegate = NSApp.delegate as AppDelegate
Vladimir Prudnikov

1
スウィフト3使用let appDelegate = NSApplication.shared().delegate as AppDelegate
ディルク

4
ではスウィフト4NSApp.delegate as? AppDelegate
ニック・

12

これがSwift 2.0バージョンです:

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

管理対象オブジェクトのコンテキストにアクセスするには:

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

        let moc = delegate.managedObjectContext

        // your code here

    }

または、ガードを使用します:

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

    let moc = delegate.managedObjectContext

    // your code here

10

SWIFT <3

exのAppDelegateクラスにメソッドを作成する

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

そして、それを別の場所で元に戻す

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

SWIFT> = 3.0

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

2
これも機能し、sharedInstanceの命名のアイデアが気に入っています。ありがとう!
ジョングリフィス

2
あなたの例では、AppDelegate呼び出すたびに新しいオブジェクトをインスタンス化しますAppDelegate().sharedInstance()
pxpgraphics

1
私はこの解決策を受け入れられた解決策よりも気に入っています(これをすべて使用しなければならない場合は、「不自然に」冗長です)。私はこの答えを見つける前にextensionforを試すことを考えていNSApplicationましたが、これははるかに優れています。今日ではおそらく、クラスで計算された読み取り専用プロパティを使用したいと思うでしょうshared。たぶん、Swift 3の更新を投稿したいですか?
Patru

1
私は実際に、使用するコードをリファクタリングstatic var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }している最中です。これは、このタイプのものに対して計算された読み取り専用プロパティを使用するSwift 3スタイルの開発とより一致しています。?リファクタリングが済んだら落とせると思いますよね?(申し訳ありませんが、コメント内のコードフォーマットは常に混乱しています。)
Patru

@ pxpgraphics UIApplicationはシングルトンクラスなので、複数のインスタンス化について心配する必要はありません。
Abhijith


6

単純にこれを試してください:

スウィフト4

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

AppDelegateのどこに:

// MARK: - Whatever
func whateverWillOccur() {

    // Your code here.

}

5

クラス名のUIApplicationDelegateハードコーディングを回避するための拡張機能を次に示し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

MacでNSApplicationDelegateこれを行うと、次のようになります'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?。これは時代遅れですか?
pkamb

@pkamb新しいプロジェクトで試したところ、このエラーはありません。私は置き換えUIApplicationDelegateによってNSApplicationDelegateおよびUIApplicationによってNSApplication
nyg


4

とても簡単です

アプリ委任インスタンス

let app = UIApplication.shared.delegate as! AppDelegate

1行の構文でメソッドを呼び出すことができます

app.callingMethod()

このコードで変数にアクセスできます

app.yourVariable = "Assigning a value"

2

私の場合、サブクラスのimport UIKit上に足りませんでしたNSManagedObject。それをインポートした後、私はそのエラーを取り除くことができましたUIApplicationの一部です。UIKit

それが他の人を助けることを願っています!!!


2

これはSwift 2.3で使用しています。

1. AppDelegateクラス

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

2. AppDelegateを呼び出す

let appDelegate = AppDelegate.sharedInstance

2
extension AppDelegate {

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

2

iOS 12.2およびSwift 5.0以降、AppDelegateは認識される記号ではありません。UIApplicationDelegateです。AppDelegateしたがって、言及する回答はすべて正しくありません。次の答えは正解であり、一部の開発者がコードのにおいを考える一部の強制アンラップを回避しています。

import UIKit

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

1
swift5では、コードから「UIApplication.delegateはメインスレッドからのみ使用する必要があります」という警告が表示されます。回答を更新できますか?
Mahesh Narla

これfatalErrorは、機能的にフォースアンラップと同等です。
pkamb


0

Xcode 6.2では、これも機能します

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

let aVariable = appDelegate.someVariable

2
v01d、それをどこから取ったのですか?
NSPratik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.