簡體   English   中英

Swift 3 迭代嵌套字典?

[英]Swift 3 iterate over a nested Dictionary?

好的,那么,快速的菜鳥警報:

給定以下數組,我如何進行最簡單的迭代(我不知道如何稱呼這個形狀:數組、字典、對象...)?

func showNotification(_ sender: [AnyHashable: Any]) { ... }

發件人[“動作”]:

可選([{"text":"Confirm","type":"response"},{"text":"Decline","type":"response"},{"link":"https://www .stackoverflow.com","text":"Website","type":"info"}])

嘗試:

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對於一個循環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;
}]

您想解碼 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)
    }
}

你在這里得到的是一個未解碼的 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")
*/

這里的數據有些可疑。 讓我們更加小心地對待數據。 這是一種從 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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM