将 userInfo [AnyHashable: Any] 转换为 [String: Any]
Convert userInfo [AnyHashable: Any] to [String: Any]
我在 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)。
这是我在控制台中打印的字典["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"
}
错误
Could not cast value of type '__NSCFString' (0x1cfa84f90) to 'NSDictionary' (0x1cfa85bc0).
很清楚。键message
的值是一个字符串
- 类型是真实类型
- 到是预期的错误类型
if let response = dict["message"] as? String, ...
对于以下答案,代码未针对编译器进行测试,可能存在一些可以轻松修复的错字问题,其中一些是故意完成的,以体现其背后的逻辑,而不是添加 if let
/guard let
、as?
等是需要的,但在解释中增加了噪音。
我不会重复 ,这是正确的并解释它失败的原因。
所以我们很清楚dict["message"]
是一个String
.
您似乎在 JSON 首字母缩略词中遗漏的一条信息代表 "N":表示法。
当您打印 dict["message"]
时,您并没有真正的 key/value 对象,您有一个表示键值对象的字符串,但不是 Swift 表示形式。您打印了 JSON 字符串化(因为它显然比十六进制数据 JSON 更具可读性)。如果在回答后打印 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)
或
let baseResponse = Mapper<NotificationModel>().map(JSONString: jsonStringifiedString)
因为有时 JSONStringified 嵌入 JSON,您可能需要在 String
或 Data
上直接调用它。
或者只是因为基本 URLSession
在其闭包中请求 returns 一个 Data
对象,而您想直接使用它。
我在 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)。
这是我在控制台中打印的字典["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"
}
错误
Could not cast value of type '__NSCFString' (0x1cfa84f90) to 'NSDictionary' (0x1cfa85bc0).
很清楚。键message
的值是一个字符串
- 类型是真实类型
- 到是预期的错误类型
if let response = dict["message"] as? String, ...
对于以下答案,代码未针对编译器进行测试,可能存在一些可以轻松修复的错字问题,其中一些是故意完成的,以体现其背后的逻辑,而不是添加 if let
/guard let
、as?
等是需要的,但在解释中增加了噪音。
我不会重复
所以我们很清楚dict["message"]
是一个String
.
您似乎在 JSON 首字母缩略词中遗漏的一条信息代表 "N":表示法。
当您打印 dict["message"]
时,您并没有真正的 key/value 对象,您有一个表示键值对象的字符串,但不是 Swift 表示形式。您打印了 JSON 字符串化(因为它显然比十六进制数据 JSON 更具可读性)。如果在回答后打印 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)
或
let baseResponse = Mapper<NotificationModel>().map(JSONString: jsonStringifiedString)
因为有时 JSONStringified 嵌入 JSON,您可能需要在 String
或 Data
上直接调用它。
或者只是因为基本 URLSession
在其闭包中请求 returns 一个 Data
对象,而您想直接使用它。