在swift 3中更新字典值

时间:2017-08-09 17:28:14

标签: ios iphone swift dictionary swift3

{
  "error": false,
  "error_msg": "Get trending data.",
  "Total_category": 2,
  "responseData": [
    {
      "categoryName": "Trending",
      "Trending": [
        {
          "category": "Trending",
          "trailerPrice": "",
          "isFavourit": null,
          "isWatchlist": null
        }
      ]
    },
    {
      "categoryName": "Comedy",
      "Comedy": [
        {
          "category": "Comedy",
          "trailerPrice": "",
          "isFavourit": null,
          "isWatchlist": null
        }
      ]
    }

  ]
}

我需要更新特定密钥**("isFavourit")**的内容,如何在swift 3中进行更新?仅更新responseData-> index[1]->comedy[]-> "isFavourit" null to 1

我可以像这样设置字典的值 responseData[1][Comedy]![0]["isFavourit"] = 1无法在swift3中工作。

如何设置“isFavourit”值1?

我刚试过像

这样的东西
(arrVideoDetail[1]["comedy"] as! [Dictionary<String,Any>])[0]["isFavourit"] = 1

上面的代码显示错误无法分配给'Any?

类型的不可变表达式

1 个答案:

答案 0 :(得分:0)

这是非常糟糕的JSON。问题是responseData数组中的字典没有一致的键。第一个有键

  "categoryName": "Trending",
  "Trending": [

但第二个有键

  "categoryName": "Comedy",
  "Comedy": [

这意味着在您取出categoryName键的值之前,您不知道第二个键的名称。所以你必须先停下来然后才能继续。

因此,假设您在名为json的字符串中包含JSON。然后:

    let d1 = try! JSONSerialization.jsonObject(with: json.data(using: .utf8)!)
    let a1 = (d1 as! [String:Any])["responseData"]
    let d2 = (a1 as! [[String:Any]])[1]
    let key = d2["categoryName"] as! String // "Comedy"
    let a2 = d2[key]!
    var d3 = (a2 as! [[String:Any]])[0]
    // ["isWatchlist": <null>, "trailerPrice": , "isFavourit": <null>, "category": Comedy]


现在d3是您要查找的内部词典,您可以根据需要进行修改。

顺便说一句,这个你的JSON是一个很好的例子,说明为什么在Swift 4中这一切都会好得多。我们可以将整个JSON解析为自定义结构的属性:

struct MyJson : Decodable {
    let error : Bool
    let error_msg : String
    let Total_category : Int
    let responseData : [ResponseData]
    struct ResponseData : Codable {
        let categoryName : String
        let unknown : [Inner]
        struct Inner : Codable {
            let category : String
            let trailerPrice : String
            let isFavourit : String?
            let isWatchList : String?
        }
        private struct CK : CodingKey {
            var stringValue: String
            init?(stringValue: String) { self.stringValue = stringValue }
            var intValue: Int?
            init?(intValue: Int) { return nil }
        }
        init(from decoder: Decoder) throws {
            let con = try! decoder.container(keyedBy: CK.self)
            self.categoryName = try! con.decode(String.self, forKey:CK(stringValue:"categoryName")!)
            let key = self.categoryName
            self.unknown = try! con.decode([Inner].self, forKey: CK(stringValue:key)!)
        }
    }
}


配置了我们的结构,解析整个JSON只是一行代码!假设您的JSON位于名为json的变量中:

let myjson = try JSONDecoder().decode(MyJson.self, from: json.data(using: .utf8)!)

您尝试访问的价值非常简单:

let fav = myjson.responseData[1].unknown[0].isFavourit

所以我所要做的就是将我的所有let变成var,现在它们都可以设置,就像你想要做的那样。

(有关此解决方案的更多信息,请参阅Swift 4 Decodable with keys not known until decoding time。)