如何在“任何”类型的对象中更新值

时间:2018-11-14 12:19:31

标签: ios swift

我有一个很大的json数据。我正在尝试描述以下情况->

JSON = {

"str1": 1,

"str2": false,

"response":

  {
    "str1": 10.2,

    "lists": [{
        "list": ["a", "b", "c"],
        "something": 1
    }, {
        "list": ["a1", "b1", "c1"],
        "something": 2
    }]

  }

}

我从服务器以[String:Any]的形式获取此json

var jsonData: Any?

func firstInitialiseJsonData(jsonData: Any?) { // Initialize jsonData by server json
     self.jsonData = jsonData
}

现在我要更新此self.jsonData。

func updateJsonData() {
     guard let newJsonData = self.jsonData as? [String : Any] else { return }
     guard let response = newJsonData["response"] as? [String : Any] else { return }
     guard var lists = response["lists"] as? [[String : Any]] else { return }

     lists.append(["list": ["a2","b2","c2"], "something" : 3])

}

但是上面的代码不起作用,因为“列表”包含复制数据。如何更新self.jsonData?任何帮助

2 个答案:

答案 0 :(得分:5)

在值类型环境中,您必须将变异的对象分配回去。使用原始集合类型时,这非常麻烦。

有了自定义结构和Decodable,它更加方便(高效)

此示例省略了所有不相关的键

let json = """
{
    "str1": 1,
    "str2": false,
    "response": {
        "str1": 10.2,
        "lists": [{
            "list": ["a", "b", "c"],
            "something": 1
        }, {
            "list": ["a1", "b1", "c1"],
            "something": 2
        }]
    }
}
"""

struct Root : Decodable {
    var response : Response
}

struct Response : Decodable {
    var lists : [List]
}

struct List : Decodable {
    let list : [String]
    let something : Int
}

let data = Data(json.utf8)

do {
    // decode the JSON to the `Root` struct, `var` makes the object mutable
    var jsonData = try JSONDecoder().decode(Root.self, from: data)
    // create a new `List`
    let newList = List(list: ["a2","b2","c2"], something: 3)
    // assign the value back to the top level object
    jsonData.response.lists.append(newList)

    print(jsonData)

} catch {
    print(error)
}

答案 1 :(得分:0)

  

但是上面的代码不起作用,因为“列表”包含复制数据。如何更新self.jsonData?

我会通过将每个碎片从其到达的位置重新分配到容器中来实现的。我现在没有时间测试以下代码,因此请注意错误,但这至少可以说明这个想法:

func updateJsonData() {
     guard var newJsonData = self.jsonData as? [String : Any] else { return }
     guard var response = newJsonData["response"] as? [String : Any] else { return }
     guard var lists = response["lists"] as? [[String : Any]] else { return }

     lists.append(["list": ["a2","b2","c2"], "something" : 3])
     response["lists"] = lists
     newJsonData["response"] = response
     self.jsonData = newJsonData
}