Swift 3迭代嵌套字典?

时间:2017-08-23 17:01:52

标签: ios swift loops

好的,快速的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;
}]

3 个答案:

答案 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
    }
}