Xavi Molina
Xavi Molina

Reputation: 31

How to pass notification data to a View Controller with Swift

I receive a notification in App Delegate with a question in the data (userInfo variable), and I need this String to be passed to the View Controller named "Question". I want this String to be shown in this variable @IBOutlet weak var question: UILabel! which is in the Question View Controller.

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
    }

    // Print full message.
    print(userInfo)
    let storyboard = UIStoryboard(name:"Main", bundle:nil)
    let question_view = storyboard.instantiateViewController(withIdentifier: "Question")
    window?.rootViewController = question_view

    completionHandler()
}

How can I pass the data to the View Controller? I've tried to access the variable from there but I didn't work. Thanks!

Upvotes: 0

Views: 2474

Answers (1)

Duncan C
Duncan C

Reputation: 131398

There are lots of ways to handle this.

You're already creating a view controller and installing it as the window's root view controller.

With that approach, all that's left is to add a string property to the target view controller and set that property. You'd then cast the question_view to the correct type and install the property.

Finally, in your view controller's viewWillAppear, install the value of the property into the view:

class QuestionViewController: UIViewController {

    public var questionString: String = ""
    @IBOutlet weak var questionLabel: UILabel!

    override func viewWillAppear(_ animated: Bool) {
       questionLabel.text = questionString
    }
}

And your app delegate method, modified appropriately:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {

    //Use a guard statement to make sure that userInfo is a String
    guard let userInfo = response.notification.request.content.userInfo as? String else {
      completionHandler()
      return
    }

    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
    }

    // Print full message.
    print(userInfo)
    let storyboard = UIStoryboard(name:"Main", bundle:nil)
    //If question_view is the correct type, set it's question_string property
    if let question_view = storyboard.instantiateViewController(withIdentifier: "Question") as QuestionViewController {
      questionString = userInfo
    window?.rootViewController = question_view

    completionHandler()
}

Note that variable names like question_view should use camelCase in Swift. You're using snake_case, which is not the convention. Your name question_view should really be questionView.

Also note that you should not try to reference the view controller's view objects directly. You should use a public string property as I've shown.

Upvotes: 3

Related Questions