Как разобрать JSON для вложенной структуры в Swift? - PullRequest
0 голосов
/ 04 октября 2018

Я собираюсь проанализировать этот JSON:

{
    "status": 1,
    "member": {
        "id": "3",
        "member_no": "1111",
        "username": "uname",
        "name": "name",
        "email": "user@name.com",
        "phone": "123 123",
        "point": "100",
        "expiry": "2019-09-22",
        "grade": {
            "id": "2",
            "name": "Member"
        }
    }
}

Я создал эту структуру:

struct User: Codable {
    var status: Int?
    var member: Member?
    var msg: String?

    struct Member: Codable {
        var id: Int?
        var member_no: String?
        var username: String?
        var name: String?
        var email: String?
        var phone: String?
        var point: String?
        var expiry: String?
        var grade: Grade?

        struct Grade: Codable {
            var id: Int?
            var name: String?
        }
    }
}

И использовать ее для декодирования:

let decoder = JSONDecoder()
let user = try decoder.decode(User.self, from: data)

Но я получил эту ошибку:

Данные не могут быть прочитаны, потому что они не в правильном формате.

Если структура только один уровень, этонет проблем:

struct User: Codable {
    var status: Int?
    var msg: String?
}

Как написать структуру, соответствующую этому JSON?

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Возможно, вы захотите попробовать следующее, что, кажется, прекрасно работает для меня.

Сначала нам нужно создать CodingKeys для нашей структуры User

При работе с кодируемым,даже если Member и Grade внутри элемента вложены друг в друга.Вы должны объявить эти структуры вне структуры User.

Как видно из приведенного ниже, член и класс должны соответствовать Codable, тогда как пользователь соответствует Decodable в расширении и инициализируется с помощью декодера, используя его в качестве контейнера.

Также, поскольку в вашем json-файле у вас есть id как String как в User, так и в Grade, но в вашем коде вы объявили их как Int, поэтому я также исправил их.

Приведенный ниже код реализует структуры и CodingKeys, как я уже упоминал выше, попытайтесь приблизиться, как я, или попробуйте скопировать его, и все будет в порядке:

Структура пользователя с CodingKeys:

struct User {
var status: Int?
var member: Member?

enum CodingKeys: String, CodingKey {
    case status = "status"
    case member = "member"
}
}

Структуры члена и класса:

struct Member: Codable {
var id: String?
var member_no: String?
var username: String?
var name: String?
var email: String?
var phone: String?
var point: String?
var expiry: String?
var grade: Grade?
}

struct Grade: Codable {
var id: String?
var name: String?
}

Расширение для пользователя для соответствия Codable:

extension User: Decodable {
init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    self.status = try container.decode(Int?.self, forKey: .status)
    self.member = try container.decode(Member?.self, forKey: .member)
}
}

Теперь создайте декодер и попробуйте декодировать его следующим образом:

    let decoder = JSONDecoder()
    let user = try! decoder.decode(User.self, from: data)

Надеюсь, это поможет и отлично сработает для вас

0 голосов
/ 04 октября 2018

xcode, вероятно, выдал вам ошибку, сказав, что ваша структура не соответствует декодируемому протоколу, вас это не заботит:]

вот как должна выглядеть ваша структура (модель)


struct User: Codable {
    let status: Int?
    let member: Member?
}</p>

<p>struct Member: Codable {
    let id, memberNo, username, name: String?
    let email, phone, point, expiry: String?
    let grade: Grade?</p>

<pre><code>enum CodingKeys: String, CodingKey {
    case id
    case memberNo = "member_no"
    case username, name, email, phone, point, expiry, grade
}

}

struct Grade: Codable {let id, name: String?}

0 голосов
/ 04 октября 2018

У вас есть строки в идентификаторах, а не целые числа:

struct User: Codable {
    var status: Int?
    var member: Member?

    struct Member: Codable {
        var id: String?
        var member_no: String?
        var username: String?
        var name: String?
        var email: String?
        var phone: String?
        var point: String?
        var expiry: String?
        var grade: Grade?

        struct Grade: Codable {
            var id: String?
            var name: String?
        }
    }
}

let decoder = JSONDecoder()
do {
    let user = try decoder.decode(User.self, from: data)
} catch {
    print(error)
}
...