【问题标题】:how to call a method in a view controller from Appdelegate in Swift?如何从 Swift 中的 Appdelegate 调用视图控制器中的方法?
【发布时间】:2019-10-30 16:57:24
【问题描述】:

这个Main Menu VC会在应用第一次启动或者用户回到应用后(应用进入后台状态后激活)打开。

每次打开这个主菜单VC,理想情况下我需要更新日期时间数据来自服务器的时间。在这个主菜单 vc 类中,我调用 getDateTimeFromServer(),然后我调用 updateUI()

但要在应用进入后台再回到前台后更新数据,需要通过Appdelegate使用函数激活getDateTimeFromServer()updateUI()

func applicationWillEnterForeground(application: UIApplication) {

    }

那么如何从 AppDelegate 激活 Main Menu VC 中存在的方法

【问题讨论】:

  • 你可以使用NotificationCenter
  • 为什么要使用 AppDelegate?为什么不制作一个你在使用 KVO 时观察到的单例?

标签: ios swift appdelegate


【解决方案1】:

您不需要在应用委托中调用视图控制器方法。在你的控制器中观察前台事件并从那里调用你的方法。

在你的 viewController viewDidLoad 中观察 UIApplicationWillEnterForeground 通知:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.yourMethod), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)

当用户进入前台时实现这个来接收回调

@objc func yourMethod() {
     // Call getDateTimeFromServer()
}

【讨论】:

    【解决方案2】:

    这些类型的消息传递在大多数情况下是通过static 上下文完成的。正如已经提到的,您也可以使用视图控制器内的通知中心来通知您的应用程序进入前台。我不鼓励您为此创建自定义通知(但也是一种可能的解决方案)。

    无论如何,对于您的具体情况,我建议您有一个包含您的数据的模型。然后创建它的共享实例。

    class MyDataModel {
    
       static var shared: MyDataModel = {
            let model = MyDataModel()
            model.reloadData()
            return model
       }()
    
       var myObjects: [MyObject]?
    
       func reloadData() {
           // load data asynchronously
       }
    }
    

    现在,当您的视图控制器需要重新加载时,它只需使用 MyDataModel.shared.myObjects 作为数据源。

    在应用委托中,您所做的就是在应用返回前台时使用 MyDataModel.shared.reloadData() 重新加载它。

    所以现在仍然缺少一个委托,所以我们添加

    protocol MyDataModelDelegate: class {
        func myDataModel(_ sender: MyDataModel, updatedObjects objects: [MyObject]?)
    }
    class MyDataModel {
    
        weak var delegate: MyDataModelDelegate?
    
       static var shared: MyDataModel = {
    

    现在,当您的视图控制器出现时,它需要将自己指定为委托MyDataModel.shared.delegate = self。并实现必须重新加载视图的协议。

    可以在模型设置器中简单地调用委托:

    }()
    
    var myObjects: [MyObject]? {
       didSet {
           delegate.myDataModel(self, updatedObjects: myObjects)
       }
    }
    
    func reloadData() {
    

    【讨论】:

      【解决方案3】:

      您可以使用一种称为Key-Value Observation的技术来做类似的事情:

      class CommonObservableData: NSObject {
          // Use @objc and dynamic to ensure enabling Key-Value Observation
          @objc dynamic var dateTime: Date?
      
          static let shared = CommonObservableData()
      
          func updateFromWeb() {
              // callWebThen is a function you will define that calls your Web API, then
              // calls a completion handler you define, passing new value to your handler
              callWeb(then: { self.dateTime = $0 })
          }
      }
      

      然后你使用 Swift 4 的新 NSKeyValueObservation 观察它。

      class SomeViewController: UIViewController {
          var kvo: NSKeyValueObservation?
          func viewDidLoad() {
              ...
              kvo = CommonObservableData.shared.observe(
                  \CommonObservableData.dateTime, { model, change in
      
                  self.label.text = "\(model.dateTime)"
      
              })
          }
      }
      

      Key-Value Observation 最初是一种 Objective-C 技术,在 Swift 4 中“有所复兴”,这种技术允许您观察属性的变化(称为 Key 在 Objective-C 中)的任何对象。

      所以,在前面的代码 sn-ps 中,我们创建了一个类,并将其设为单例,这个单例有一个名为 dateTime 的可观察属性,我们可以在其中观察该属性的变化,并在其中进行任何更改此属性会自动调用我们可以更新 UI 的方法。

      在此处了解 KVO:

      Key-Value Observation Apple Programming Guide

      Key-Value Observation using Swift 4

      另外,如果你喜欢 Rx 和 RFP(反应式函数式编程),你可以使用 RxSwift 并使用它以更简洁的方式进行观察。

      【讨论】:

        【解决方案4】:

        在 swift 4 和 5 中,通知名称已更改为以下代码适用于两者。

            notifyCenter.addObserver(self, selector: #selector(new), name:UIApplication.willEnterForegroundNotification, object: nil)
        
         @objc func  new(){}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-23
          • 1970-01-01
          • 1970-01-01
          • 2021-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-27
          相关资源
          最近更新 更多