簡體   English   中英

如何在 Swift 中將 JSON 解析為嵌套結構?

[英]How to parse JSON to nested struct in Swift?

我將解析這個 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只有一層,那就沒問題了:

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

如何編寫一個結構來匹配這個 JSON?

您可能想嘗試以下方法,這對我來說似乎很好用。

首先,我們需要為我們的結構User創建CodingKeys

使用 codable 時,即使Member內部的MemberGrade彼此嵌套。 您應該在 User 結構之外聲明這些結構。

正如您在下面看到的一樣 Member 和 Grade 應該符合Codable ,而 User 在擴展中符合Decodable並通過將其用作容器來使用解碼器進行初始化。

此外,由於在您的 json 文件中,您在 User 和 Grade 中都將id設為String ,但在您的代碼中,您將它們聲明為Int因此我也修復了它們。

下面的代碼實現了我上面提到的 structs 和 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)

我希望這對你有幫助並且適合你

xcode 可能給你拋出了一個錯誤,說你的結構不符合可解碼協議,你不關心它:]

這是你的結構(模型)應該是什么樣子


struct User: Codable {
    let status: Int?
    let member: Member?
}

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

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? }

嘗試這個

import Foundation

struct User: Codable {
    let status: Int
    let member: Member
}

struct Member: Codable {
    let id, memberNo, username, name: String
    let email, phone, point, expiry: String
    let grade: Grade

    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
}

struct User: Codable { var status: Int? var 成員:成員? var msg:字符串?

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?
    }
}

}

您在 id 中有字符串而不是整數:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM