简体   繁体   中英

What is correct way to notify view controller from AppDelegate?

I registered my application to open specific file type (cvs in my case). So when user touches "Open in -> My App"

application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:])

function is triggered. In this function I read data from file to local array. In my View Controller I need to display above data. So what is correct way to notify VC that data were received and pass data to it?

You need to post a notification like this:

Somewhere in your Constants file:

extension Notification.Name {
    public static let myNotificationKey = Notification.Name(rawValue: "myNotificationKey")
}

In AppDelegate:

let userInfo = [ "text" : "test" ] //optional
NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)

In ViewController's viewDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(self.notificationReceived(_:)), name: Notification.Name.myNotificationKey, object: nil)

Callback in view controller:

func notificationReceived(_ notification: Notification) {
    //getting some data from userInfo is optional
    guard let text = notification.userInfo?["text"] as? String else { return } 
    //your code here
}

The above answer by Alex works, if your view controller that handles the notification happens to be on screen when the notification comes in, but often times its not. In

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any])

You want to update your badge count, and then check the notification. Depending on what kind of notification you have you either handle it silently (perhaps using the Notification Center method above) or you launch the appropriate view controller and either pass it the whole notification or just the id and have the view controller call your API with the id to get all of the details. You do this just as you would normally change view controllers, so if its a navigation controller, you instantiate the new view controller, pass it the data, then push it on the navigation controller.

    let notificationTableViewController = UIStoryboard(name: Identifiers.Storyboard.Notification, bundle: nil).instantiateViewController(withIdentifier: String(describing: NotificationTableViewController.self)) as!
    NotificationTableViewController
    controller.notificationId = notificationId
    rootNavigationController?.pushViewController(notificationTableViewController, animated: true)

If you have a tab bar application you switch tabs first. If you have some kind of custom navigation, you need to call the appropriate method on your container class.

Don't need to use Notifications. Your app will be a mess.

JLRoutes can help you! see the examples in github page.

Define some URLs just like xxxDetail, xxxList with JLRoutes in your app. when application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) get called. you just need to call [JLRoutes route: URL]

You can also handle didReceiveRemoteNotification in the same way.

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
 // get URL from userInfo
 // [JLRoutes route: url];
}

let the server-side send you userInfo with URLs you defined.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM