简体   繁体   中英

How to pass data to a ViewController from push notification through the storyboard?

This is a fragment of my iOS app:

在此输入图像描述

where the Tab Bar Controller is my root controller followed by a Navigation Controller followed by a Table View Controller followed by a final View Controller . When a push notification arrives, I need to pass some data to this final view controller (in order to fill those blank UITextView and a UITextField ). This is the code I have written up to now but I don't know how to go on:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    //let tab :UITabBarController = self.window?.rootViewController as! UITabBarController
    //tab.selectedViewController = tab.viewControllers![3]
    print("NOTIFICA \n")
    print(userInfo)

    let tab :UITabBarController = self.window?.rootViewController as! UITabBarController
    tab.selectedViewController = tab.viewControllers![2]
}

This code is supposed to let me access to the 3-rd view controller of the tab bar controller but I need to go beyond it to the final view controller and pass userInfo to it. How shall I do? Thanks to all.

UPDATE

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    //let tab :UITabBarController = self.window?.rootViewController as! UITabBarController
    //tab.selectedViewController = tab.viewControllers![3]
    print("NOTIFICA \n")
    print(userInfo)
    application.applicationIconBadgeNumber = 0
    application.cancelAllLocalNotifications()
    NSNotificationCenter.defaultCenter().postNotificationName("MyNotificationReceived", object: userInfo)
}


class DynamicEventsViewController:UIViewController {

@IBOutlet weak var dynamicEventTitle:UITextField!
@IBOutlet weak var dynamicEventDescription:UITextView!

var eventTitle:String!
var eventDescription:String!

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.titleView = UIImageView(image: UIImage(named: "icons/bar.png"))
    self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(DynamicEventsViewController.notificatonArrived(_:)), name: "MyNotificationReceived", object: nil)

    self.dynamicEventTitle.text = self.eventTitle.uppercaseString
    self.dynamicEventDescription.text = self.eventDescription
}

func notificatonArrived(notification: NSNotification) {
    let userInfo:[NSObject : AnyObject] = notification.userInfo!
    self.eventTitle = userInfo["aps"]!["alert"] as! String
    self.eventDescription = userInfo["aps"]!["description"] as! String
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

}

I think there are two questions to this post.

  1. How to take the user to the final view controller upon receiving a push notification?
  2. How to pass the payload of the push notification to the final view controller?

For #1, you will have to first determine how the user would normally go to the final view controller. Based on the storyboard he would switch to the third tab, select an item in the table view which would then load the final view controller. So you will have to do this programatically by switching the Tab controller to the third view controller, then getting the navigation controller and then simulating the selection of an item in the table view which will then load the final view controller.

For #2 notifications may not work properly because the final view controller may not be loaded by the time the notification is sent. Its hard to sync this. In this case you can save the push notification payload in user defaults using NSStandardUserDefaults . Then in the final view controller you can check if there is any prefs already stored as a part of this flow and if so load it and populate the text field and text view with the values and delete the prefs so that next time it is loaded the values are not populated.

This kind of decouples the push notification and saving of the data to be preloaded in the final view controller from the actual loading of this data in the final view controller.

Another option is to just load the final view controller as a modal view controller and pass the data to that controller at the time of receiving the notification itself. Of course this is applicable only if your final view controller's data model doesn't require it to always comes from the table view controller.

You can use NSNotificationClass , you can read a tutorial here . Register the notification in (say) FinalViewController

class FinalViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FinalViewController.notificatonArrived(_:)), name: "MyNotificationReceived", object: nil)
  }

  func notificatonArrived(notification: NSNotification) {
    //do you updation of labels here
    let userInfo = notification.userInfo
  }

  deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
  }
}

And when you receive the notification the do this

  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    print("NOTIFICA \n")
    print(userInfo)

    NSNotificationCenter.defaultCenter().postNotificationName("MyNotificationReceived", object: userInfo)
  }

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