iOS: распаковать JSON с массивом словарного массива

Я хочу проанализировать файл JSON с помощью библиотеки Unbox. JSON является массивом словарного массива. Как мы можем сделать это? Я попытался использовать keypath и почти не смог разобрать его. Мне нужен массив разделов.

Я попытался с единой иерархией и смог разобрать ее.

Используемая библиотека: 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!))

1 ответ

Решение

Вам понадобится несколько вложенных structs для хранения всех доступных данных. Минимальная структура данных выглядит примерно так:

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")
            }
        }
    }
}

Пример json и стратегия разбора:

// 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)
}

Только для Swift 4 или новее

Если вы не связаны с версией Swift, есть еще более простой способ добиться этого:

// 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)
}
Другие вопросы по тегам