如何使用 Swift 将通知数据传递给视图控制器

How to pass notification data to a View Controller with Swift

我在 App Delegate 中收到一条通知,其中包含数据(userInfo 变量)中的一个问题,我需要将此字符串传递给名为 "Question" 的视图控制器。我希望这个字符串显示在这个变量中 @IBOutlet weak var question: UILabel! 它在问题视图控制器中。

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()
}

如何将数据传递给视图控制器?我试图从那里访问变量,但没有成功。谢谢!

有很多方法可以解决这个问题。

您已经创建了一个视图控制器并将其安装为 window 的根视图控制器。

使用这种方法,剩下的就是向目标视图控制器添加一个字符串 属性 并设置它 属性。然后将 question_view 转换为正确的类型并安装 属性.

最后,在您的视图控制器的 viewWillAppear 中,将 属性 的值安装到视图中:

class QuestionViewController: UIViewController {

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

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

以及您的应用委托方法,适当修改:

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()
}

请注意,question_view 等变量名应在 Swift 中使用驼峰式命名。您使用的是 snake_case,这不是惯例。你的名字 question_view 真的应该是 questionView.

另请注意,您不应尝试直接引用视图控制器的视图对象。您应该使用 public 字符串 属性,如我所示。