How to update value in a “Any” type Object










0















I've a big json data. I'm trying to describe the scenario below ->



JSON = 

"str1": 1,

"str2": false,

"response":


"str1": 10.2,

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






I get this json from server as [String : Any]



var jsonData: Any?

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



Now I want to update this 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])




But above code is not working, because "lists" contains copy data. How can I update self.jsonData? Any Help










share|improve this question






















  • What about using Decodable?

    – Ahmad F
    Nov 14 '18 at 12:35











  • @Ahmad F can you elaborate?

    – Symon
    Nov 14 '18 at 12:43











  • Just take a look at vadian's answer, he is using decodable :)

    – Ahmad F
    Nov 14 '18 at 13:18















0















I've a big json data. I'm trying to describe the scenario below ->



JSON = 

"str1": 1,

"str2": false,

"response":


"str1": 10.2,

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






I get this json from server as [String : Any]



var jsonData: Any?

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



Now I want to update this 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])




But above code is not working, because "lists" contains copy data. How can I update self.jsonData? Any Help










share|improve this question






















  • What about using Decodable?

    – Ahmad F
    Nov 14 '18 at 12:35











  • @Ahmad F can you elaborate?

    – Symon
    Nov 14 '18 at 12:43











  • Just take a look at vadian's answer, he is using decodable :)

    – Ahmad F
    Nov 14 '18 at 13:18













0












0








0


1






I've a big json data. I'm trying to describe the scenario below ->



JSON = 

"str1": 1,

"str2": false,

"response":


"str1": 10.2,

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






I get this json from server as [String : Any]



var jsonData: Any?

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



Now I want to update this 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])




But above code is not working, because "lists" contains copy data. How can I update self.jsonData? Any Help










share|improve this question














I've a big json data. I'm trying to describe the scenario below ->



JSON = 

"str1": 1,

"str2": false,

"response":


"str1": 10.2,

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






I get this json from server as [String : Any]



var jsonData: Any?

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



Now I want to update this 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])




But above code is not working, because "lists" contains copy data. How can I update self.jsonData? Any Help







ios swift






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 12:19









SymonSymon

163




163












  • What about using Decodable?

    – Ahmad F
    Nov 14 '18 at 12:35











  • @Ahmad F can you elaborate?

    – Symon
    Nov 14 '18 at 12:43











  • Just take a look at vadian's answer, he is using decodable :)

    – Ahmad F
    Nov 14 '18 at 13:18

















  • What about using Decodable?

    – Ahmad F
    Nov 14 '18 at 12:35











  • @Ahmad F can you elaborate?

    – Symon
    Nov 14 '18 at 12:43











  • Just take a look at vadian's answer, he is using decodable :)

    – Ahmad F
    Nov 14 '18 at 13:18
















What about using Decodable?

– Ahmad F
Nov 14 '18 at 12:35





What about using Decodable?

– Ahmad F
Nov 14 '18 at 12:35













@Ahmad F can you elaborate?

– Symon
Nov 14 '18 at 12:43





@Ahmad F can you elaborate?

– Symon
Nov 14 '18 at 12:43













Just take a look at vadian's answer, he is using decodable :)

– Ahmad F
Nov 14 '18 at 13:18





Just take a look at vadian's answer, he is using decodable :)

– Ahmad F
Nov 14 '18 at 13:18












2 Answers
2






active

oldest

votes


















0















But above code is not working, because "lists" contains copy data. How can I update self.jsonData?




I'd do it by reassigning each of the pieces back to the container from whence they came. I don't have time to test the following code right now, so watch out for errors, but this should at least illustrate the idea:



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






share|improve this answer


















  • 1





    Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

    – Symon
    Nov 15 '18 at 1:13


















5














In a value type environment you have to assign the mutated object back. This is very cumbersome when using primitive collection types.



With custom structs and Decodable it's much more convenient (and efficient)



This example omits all irrelevant keys



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)






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300105%2fhow-to-update-value-in-a-any-type-object%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0















    But above code is not working, because "lists" contains copy data. How can I update self.jsonData?




    I'd do it by reassigning each of the pieces back to the container from whence they came. I don't have time to test the following code right now, so watch out for errors, but this should at least illustrate the idea:



    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






    share|improve this answer


















    • 1





      Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

      – Symon
      Nov 15 '18 at 1:13















    0















    But above code is not working, because "lists" contains copy data. How can I update self.jsonData?




    I'd do it by reassigning each of the pieces back to the container from whence they came. I don't have time to test the following code right now, so watch out for errors, but this should at least illustrate the idea:



    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






    share|improve this answer


















    • 1





      Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

      – Symon
      Nov 15 '18 at 1:13













    0












    0








    0








    But above code is not working, because "lists" contains copy data. How can I update self.jsonData?




    I'd do it by reassigning each of the pieces back to the container from whence they came. I don't have time to test the following code right now, so watch out for errors, but this should at least illustrate the idea:



    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






    share|improve this answer














    But above code is not working, because "lists" contains copy data. How can I update self.jsonData?




    I'd do it by reassigning each of the pieces back to the container from whence they came. I don't have time to test the following code right now, so watch out for errors, but this should at least illustrate the idea:



    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







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 14 '18 at 15:46









    CalebCaleb

    109k16152239




    109k16152239







    • 1





      Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

      – Symon
      Nov 15 '18 at 1:13












    • 1





      Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

      – Symon
      Nov 15 '18 at 1:13







    1




    1





    Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

    – Symon
    Nov 15 '18 at 1:13





    Thanks for Reply. Your answer is exactly fit for me. Basically this is my office project and I can not change the whole thing like taking json as String and using decodable to extract answer

    – Symon
    Nov 15 '18 at 1:13













    5














    In a value type environment you have to assign the mutated object back. This is very cumbersome when using primitive collection types.



    With custom structs and Decodable it's much more convenient (and efficient)



    This example omits all irrelevant keys



    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)






    share|improve this answer



























      5














      In a value type environment you have to assign the mutated object back. This is very cumbersome when using primitive collection types.



      With custom structs and Decodable it's much more convenient (and efficient)



      This example omits all irrelevant keys



      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)






      share|improve this answer

























        5












        5








        5







        In a value type environment you have to assign the mutated object back. This is very cumbersome when using primitive collection types.



        With custom structs and Decodable it's much more convenient (and efficient)



        This example omits all irrelevant keys



        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)






        share|improve this answer













        In a value type environment you have to assign the mutated object back. This is very cumbersome when using primitive collection types.



        With custom structs and Decodable it's much more convenient (and efficient)



        This example omits all irrelevant keys



        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)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 12:56









        vadianvadian

        148k14159178




        148k14159178



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300105%2fhow-to-update-value-in-a-any-type-object%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            27

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            Category:Rhetoric