iosswiftswift3.2unbox

iOS : Unbox JSON with array of dictionary array


I want to parse a JSON file using Unbox library. The JSON is an array of dictionary array. How can we do that? I tried using keypath and all but unable to parse it. I need array of section.

I tried with single hierarchy and able to parse it.

Library used:https://github.com/JohnSundell/Unbox

{
    "content": [
    {
        "section": [
         {
            "title": "Test1"
         },
         {
            "title": "Test2"
         }
         ]
    },
    {
        "section": [
        {
            "title": "Test1"
        },
        {
            "title": "Test2"
        }
        ]
    }
    ]
}

struct Data : Unboxable {
    let title: String

    init(title: String) {
        self.title = title  
    }
    init(unboxer: Unboxer) throws {
        self.title = try unboxer.unbox(key: "title")
    }
}

let dataArray : Data = try unbox(data: Data(contentsOf: url!))

Solution

  • You will need some nested structs to hold all of the data available. The minimal data structure is something like:

    struct MyData: Unboxable {
        let content: [Content]
        init(unboxer: Unboxer) throws {
            content = try unboxer.unbox(key: "content")
        }
    
        // Nested structure for holding `Content` type
        struct Content: Unboxable {
            let section: [Section]
            init(unboxer: Unboxer) throws {
                section = try unboxer.unbox(key: "section")
            }
    
            // Nested structure for holding `Section` type
            struct Section: Unboxable {
                let title: String
                init(unboxer: Unboxer) throws {
                    title = try unboxer.unbox(key: "title")
                }
            }
        }
    }
    

    The example json and parsing strategy:

    // Eventually, this is the data you maybe got from any server response
    let jsonData = """
    {
    "content": [{
    "section": [{
    "title": "Test1"
    },
    {
    "title": "Test2"
    }
    ]
    },
    {
    "section": [{
    "title": "Test3"
    },
    {
    "title": "Test4"
    }
    ]
    }
    ]
    }
    """.data(using: .utf8)!
    
    // Now parse this 
    do {
        let myData = try unbox(data: jsonData) as MyData
        print(myData.content[0].section[0].title) //Test1
        print(myData.content[0].section[1].title) //Test2
        print(myData.content[1].section[0].title) //Test3
        print(myData.content[1].section[1].title) //Test4
    } catch {
        print(error)
    }
    

    Only for Swift 4 or later

    If you aren't bound to the Swift version, there is even more simpler way to achieve this:

    // Your data structure goes this
    struct MyData: Codable {
        let content: [Content]
    
        struct Content: Codable {
            let section: [Section]
    
            struct Section: Codable {
                let title: String
            }
        }
    }
    // That's it
    
    // Now you can parse the data like this:
    do {
        let myData = try JSONDecoder().decode(MyData.self, from: jsonData)
        print(myData.content[0].section[0].title) //Test1
        print(myData.content[0].section[1].title) //Test2
        print(myData.content[1].section[0].title) //Test3
        print(myData.content[1].section[1].title) //Test4
    } catch {
        print(error)
    }