将userInfo [AnyHashable:Any]转换为[String:Any]

时间:2019-01-06 12:48:39

标签: swift push-notification apple-push-notifications

我在didreceiveRemoteNotification中收到通知,但无法将userInfo强制转换为[String:Any]类型的字典

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    let dict = userInfo as! [String: Any]
    if let response = dict["message"] as? [String: Any], let baseResponse = Mapper<NotificationModel>().map(JSON: response) {
      //do some stuff
    }
}

当我尝试将dict [“ message”]投射为! [String:Any]错误发生,它说:

无法将类型'__NSCFString'(0x1cfa84f90)的值强制转换为'NSDictionary'(0x1cfa85bc0)。

在控制台中将其打印为dict [“ message”]

▿ Optional<Any>
  - some : {"sender":

{"avatar_url":"http:\/\/api.moneyar.com\/APIs\/images\/15783070400.jpg","user_id":"15783","name":"mahdi moqadasi"}

,"conversation_id":"15783"

,"message_id":103597,

"time":1546778745,

"type":1,"message":"foo"

}

2 个答案:

答案 0 :(得分:2)

对于以下答案,该代码未针对编译器进行测试,可能存在一些容易解决的错字问题,其中某些错意是为了行使其背后的逻辑而故意做的,而不是与{{1}相加} / if letguard let等,但会在说明中增加噪音。

我不会重复@vadian answer,这是正确的解释为什么会失败。

所以我们很清楚as?dict["message"]

您似乎在JSON首字母缩略词中缺少的一条信息就是“ N”表示法。

在打印String时,实际上并没有键/值对象,但有一个String表示键值对象,但没有Swift表示形式。您打印了JSON Stringified(因为十六进制数据JSON显然更具可读性)。如果在回答后打印dict["message"],则会看到输出结构可能不同。

因此,一如既往,您的基本工具是:

jsonDict

那我们就做吧!

Data <== data(encoding:)/init(data:encoding:) ==> String
Data <== jsonObject(with:options:)/data(withJSONObject:options:) ==> Array or Dictionary //I bypass voluntarily the specific case of String at top level

如果我是你,如果没有办法做以下事情,我会调查let jsonStringifiedString = dict["message"] as String let jsonStringifiedData = jsonStringifiedString.data(using: .utf8) as Data let jsonDict = try JSONSerialization.jsonObject(with: jsonStringifiedData, options: []) as [String: Any] let baseResponse = Mapper<NotificationModel>().map(JSON: jsonDict)

Mapper

let baseResponse = Mapper<NotificationModel>().map(JSONData: jsonStringifiedData)

因为有时JSON中嵌入了JSONStringified,所以您可能需要在let baseResponse = Mapper<NotificationModel>().map(JSONString: jsonStringifiedString) String上直接调用它。 或仅仅因为基本的Data请求在其闭包中返回了URLSession对象,而您想直接使用它。

答案 1 :(得分:1)

错误

  

无法将类型'__NSCFString'(0x1cfa84f90)的值强制转换为'NSDictionary'(0x1cfa85bc0)。

很清楚。键message的值是一个字符串

  • 类型真实类型
  • 是预期的错误类型

if let response = dict["message"] as? String, ...