好的,快速的noob警报:
如何在给定以下数组的情况下进行最简单的迭代(我不知道该怎么称为这个形状:数组,字典,对象......)?
func showNotification(_ sender: [AnyHashable: Any]) { ... }
sender [“actions”]:
可选([{ “文本”: “确认”, “类型”: “应答”},{ “文本”: “拒绝”, “类型”: “应答”},{ “链接”:“HTTPS: //www.stackoverflow.com”, “文本”: “网站”, “类型”: “信息”}])
的尝试:
if let result = sender["actions"] {
print("YES \(result)")
for action in result as! [String] {
print(action)
}
}
the above prints
:
YES [{"text":"Confirm","type":"response"},{"text":"Decline","type":"response"},{"link":"https:\/\/www.stackoverflow.com","text":"Website","type":"info"}]
...但是,返回以下错误:
Could not cast value of type '__NSCFString' (0x1a7c28d50) to 'NSArray' (0x1a7c297c8)
这里的最终目标是简单地分别处理每个动作,即:
{"text":"Confirm","type":"response"}
{"text":"Decline","type":"response"
等...
Swift是否有map
函数...仅供参考我是从Java和JavaScript世界进来的...... swiftyjson
对于一个循环来说似乎有点沉重。
谢谢,一如既往地感谢任何帮助和方向!
修改
这是通过传递给函数sender
:
sender: [AnyHashable("title"): title!, AnyHashable("message"): message, AnyHashable("message_id"): 0:1503511875428318%03300c3203300c32, AnyHashable("id"): 1497708240713, AnyHashable("actions"): [{"text":"Confirm","type":"response"},{"text":"Decline","type":"response"},{"link":"https:\/\/www.notifyd.com","text":"Website","type":"info"}], AnyHashable("aps"): {
"content-available" = 1;
}]
答案 0 :(得分:3)
您想要解码JSON字符串,然后转换为Dictionary:
的数组if
// cast sender["actions"] to String
let actionsString = sender["actions"] as? String,
// decode data of string and then cast to Array<Dictionary<String, String>>
let actionsStringData = actionsString.data(using: .utf8),
let result = try JSONSerialization.jsonObject(with: actionsStringData, options: []) as? [[String : String]] {
print("YES \(result)")
for action in result {
print(action)
}
}
答案 1 :(得分:0)
您在这里获得的是未解码的JSON字符串,这是真的吗?在这种情况下,Swift 4让这很容易:
struct S : Decodable {
let link : String?
let text : String
let type : String
}
if let acts = sender["actions"] as? String {
let data = acts.data(using: .utf8)!
if let arr = try? JSONDecoder().decode(Array<S>.self, from: data) {
arr.forEach {print($0)}
}
}
/*
S(link: nil, text: "Confirm", type: "response")
S(link: nil, text: "Decline", type: "response")
S(link: Optional("https://www.stackoverflow.com"), text: "Website", type: "info")
*/
答案 2 :(得分:0)
这里有数据可疑。让我们更仔细地对待数据。这是从JSON对象,JSON数组,Data对象或字符串中获取JSON的方法。
enum JsonError: Error { case notJson; case notJsonArray }
func json(from any: Any?) throws -> Any {
if let json = any as? [String: Any] { return json }
if let json = any as? [Any] { return json }
if let data = any as? Data {
return try JSONSerialization.jsonObject(with: data)
}
if let string = any as? String, let data = string.data(using: .utf8) {
return try JSONSerialization.jsonObject(with: data)
}
throw JsonError.notJson
}
既然我对JSON对象更加小心,我应该得到我想要的或者更多关于错误的信息。
func showNotification(_ sender: [AnyHashable: Any]) {
do {
guard let result = try json(from: sender["actions"]) as? [Any] else {
throw JsonError.notJsonArray
}
print("YES \(result)")
for action in result {
print("Action: \(action)")
}
} catch {
// Do Something
}
}