【问题标题】:Swift read userInfo of remote notificationSwift读取远程通知的userInfo
【发布时间】:2015-04-20 04:51:52
【问题描述】:

当我收到这样的远程通知时,我实现了一个打开 AlertView 的功能:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){
        var notifiAlert = UIAlertView()
        var NotificationMessage : AnyObject? =  userInfo["alert"]
        notifiAlert.title = "TITLE"
        notifiAlert.message = NotificationMessage as? String
        notifiAlert.addButtonWithTitle("OK")
        notifiAlert.show()
}

但 NotificationMessage 始终为零。

我的 json 有效负载如下所示:

{"aps":{"alert":"Testmessage","badge":"1"}}

我正在使用 Xcode 6、Swift 并且正在为 iOS8 进行开发。 我现在搜索了几个小时,但没有找到任何有用的信息。 通知工作得很好..如果我点击它,警报视图就会打开。 我的问题是,我无法从 userInfo 中获取数据。

【问题讨论】:

    标签: ios json swift push-notification userinfo


    【解决方案1】:

    userInfo 字典的根级项是"aps",而不是"alert"

    尝试以下方法:

    if let aps = userInfo["aps"] as? NSDictionary {
        if let alert = aps["alert"] as? NSDictionary {
            if let message = alert["message"] as? NSString {
               //Do stuff
            }
        } else if let alert = aps["alert"] as? NSString {
            //Do stuff
        }
    }
    

    Push Notification Documentation

    【讨论】:

    • 这在客观 C++ 中看起来如何?
    • 很高兴您已经通知 OP 根级别项目是 aps 而不是在 userInfo dic 中提醒 .... 但是如何找出 iOS 中的正确键和字典结构系统发送通知 userInfo 字典。在 swift 4 文档中,我可以看到 Notification.Name 中所有标准化的通知名称,但我看不到任何文档说...这是随特定通知发送的 userInfo 字典,这里是键..?
    • 是否可以在aps中添加更多参数?
    【解决方案2】:

    方法(Swift 4):

    func extractUserInfo(userInfo: [AnyHashable : Any]) -> (title: String, body: String) {
        var info = (title: "", body: "")
        guard let aps = userInfo["aps"] as? [String: Any] else { return info }
        guard let alert = aps["alert"] as? [String: Any] else { return info }
        let title = alert["title"] as? String ?? ""
        let body = alert["body"] as? String ?? ""
        info = (title: title, body: body)
        return info
    }
    

    用法:

    let info = self.extractUserInfo(userInfo: userInfo)
    print(info.title)
    print(info.body)
    

    【讨论】:

      【解决方案3】:

      斯威夫特 5

      struct Push: Decodable {
          let aps: APS
          
          struct APS: Decodable {
              let alert: Alert
              
              struct Alert: Decodable {
                  let title: String
                  let body: String
              }
          }
          
          init(decoding userInfo: [AnyHashable : Any]) throws {
              let data = try JSONSerialization.data(withJSONObject: userInfo, options: .prettyPrinted)
              self = try JSONDecoder().decode(Push.self, from: data)
          }
      }
      

      用法:

      guard let push = try? Push(decoding: userInfo) else { return }
      let alert = UIAlertController(title: push.aps.alert.title, message: push.aps.alert.body, preferredStyle: .alert)
      

      【讨论】:

        【解决方案4】:

        对我来说,当我从Accengage 发送消息时,以下代码有效 -

        private func extractMessage(fromPushNotificationUserInfo userInfo:[NSObject: AnyObject]) -> String? {
            var message: String?
            if let aps = userInfo["aps"] as? NSDictionary {
                if let alert = aps["alert"] as? NSDictionary {
                    if let alertMessage = alert["body"] as? String {
                        message = alertMessage              
                    }
                }
            }
            return message
        }
        

        与 Craing Stanford 的答案的唯一区别是 key 我用来从 alert 实例中提取消息的 body 是不同的。请参阅下文了解更多信息 -

        if let alertMessage = alert["message"] as? NSString
        

        if let alertMessage = alert["body"] as? String
        

        【讨论】:

          【解决方案5】:

          这是我的 objC 版本

          if (userInfo[@"aps"]){
              NSDictionary *aps = userInfo[@"aps"];
              if (aps[@"alert"]){
                  NSObject *alert = aps[@"alert"];
                  if ([alert isKindOfClass:[NSDictionary class]]){
                      NSDictionary *alertDict = aps[@"alert"];
                      if (alertDict[@"message"]){
                          NSString *message = alertDict[@"message"];
                      }
                  }
                  else if (aps[@"alert"]){
                      NSString *alert = aps[@"alert"];
                  }
              }
          }
          

          【讨论】:

            【解决方案6】:

            应在应用处于活动状态时显示警报。所以检查状态是否处于活动状态。

            func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
                if application.applicationState == .active {
                  if let aps = userInfo["aps"] as? NSDictionary {
                    if let alertMessage = aps["alert"] as? String {
                      let alert = UIAlertController(title: "Notification", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
                      let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                      alert.addAction(action)
                      self.window?.rootViewController?.present(alert, animated: true, completion: nil)
                    }
                  }
                }
                completionHandler(.newData)
              }
            

            如果用户需要消息,那么他可以从这里得到警报消息。

            【讨论】:

              【解决方案7】:

              我使用 APNs Provider 和 json payload 如下

              {
                "aps" : {
                  "alert" : {
                    "title" : "I am title",
                    "body" : "message body."
                  },
                "sound" : "default",
                "badge" : 1
                }
              }
              

              由于提供者将其作为 JSON 定义的字典生成,iOS 将其转换为 NSDictionary 对象,没有 Dictionary 之类的下标,但可以使用 value(forKey:)

              来自here的参考

              这是我为 Swift 4 设计的方式

              func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
                  guard application.applicationState == .active else { return }
                  guard let alertDict = ((userInfo["aps"] as? NSDictionary)?.value(forKey: "alert")) as? NSDictionary,
                      let title = alertDict["title"] as? String,
                      let body = alertDict["body"] as? String
                      else { return }
                  let alertController = UIAlertController(title: title, message: body, preferredStyle: .alert)
                  let okAct = UIAlertAction(title: "Ok", style: .default, handler: nil)
                  alertController.addAction(okAct)
                  self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
                  completionHandler(UIBackgroundFetchResult.noData)
              }
              

              【讨论】:

                猜你喜欢
                • 2016-06-16
                • 2018-07-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-11-01
                • 1970-01-01
                • 2018-05-03
                相关资源
                最近更新 更多