如何从 viewController 到 appdelegate 进行通信?

How do a comunication from viewController to appdelegate?

我想与我的 appdelegate 通信,换句话说,我想从多个视图向 AppDelegate 发送数据,这可能吗?

我找到了这段代码

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

本题:

是否可以使用 NSNotification 进行通信?

是的,Notification 可以做你想做的事。从视图控制器中,post 通知:

class YourViewController: UIViewController {

    ...

    @IBAction func buttonPressed(_ sender: Any) {
        NotificationCenter.default.post(name: "ViewControllerButtonPressed", object: nil)
    }
}

然后,在您的 AppDelegate 中,添加一个 Notification 观察者以观察此通知名称的 posts:

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        ...

        //Add the observer
        //This observer will call the "doSomething" function every time NotificationCenter.default.post(name: "ViewControllerButtonPressed", object: nil) is called
        NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: "ViewControllerButtonPressed", object: nil)
    }

    @objc func doSomething() {
        print("A button was pressed in one of your view controllers!")
    }

}

补充建议: 为了使事情更简单,您可以扩展 Notification.Name 为名称创建静态 String 值:

public extension Notification.Name {
    static let ButtonPressed = Notification.Name("ViewControllerButtonPressed")
}

这可以取代

NotificationCenter.default.post(name: "ViewControllerButtonPressed", object: nil)

NotificationCenter.default.post(name: NSNotification.Name.ButtonPressed, object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: "ViewControllerButtonPressed", object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: NSNotification.Name.ButtonPressed, object: nil)

实施上述方法是可选的,但可以防止在使用 Notifications 时出现拼写错误。

我不建议您使用 NotificationCenter。他们有一些限制。

  1. 从每个 ViewController,您必须使用 post 函数,并且在 App Delegate 中您必须添加观察者。那么只有你可以使用NotificationCenter的post方法。就像上面大卫给你展示的那样。

  2. 如果您必须从不同的视图控制器调用 App Delegate 的不同功能,那么您必须再次在 App Delegate 中添加不同的观察者。之后就可以调用App delegate的不同功能了

但是使用您在问题中定义的上述方法。您不需要添加观察者。借助此实例,您可以调用 App 委托的任何方法。我会给你举个例子:-

 let appDelegate = UIApplication.shared.delegate as! AppDelegate

 @UIApplicationMain
 @objc class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var isUpdate: Bool = false

func setValuesOfAppDelegate() {
    print("123")
}

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    IQKeyboardManager.shared.enable = true

    if UserDefaults.standard.bool(forKey: UserDefaultKey.isAutoLogin) == false {
        startViewController()
    } else {
        goToRootViewAfterLogin()
    }

    AppUserDefaults.set(KEnglish, forKey: KSetLanguage)
    self.registerForPushNotifications(application)

    return true
  }
}

示例如何使用 App 委托实例中的 App 委托变量和函数。你可以看一下代码。

  1. 在第一个示例中,我从 ClassA 设置 App Delegate 的变量。

  2. 在第二个示例中,我能够从 ClassB 调用 App Delegate 的功能。

  3. 在第三个示例中,我能够设置 App Delegate Class 变量的值并能够同时访问该函数。

    class ClassA: UIViewController {
    
        //MARK:- View Life Cycle
        override func viewDidLoad() {
          super.viewDidLoad()
            appDelegate.isUpdate = true
        }
    }
    
    class ClassB: UIViewController {
    
         //MARK:- View Life Cycle
         override func viewDidLoad() {
           super.viewDidLoad()
            appDelegate.setValuesOfAppDelegate()
         }   
    }
    
    class ClassC: UIViewController {
    
         //MARK:- View Life Cycle
         override func viewDidLoad() {
           super.viewDidLoad()
            appDelegate.isUpdate = true
            appDelegate.setValuesOfAppDelegate()
        } 
     }