解码嵌套的 JSON Swift

用户9779811

我必须解码由响应下载的这种类型的 JSON。JSON 是这样的,我需要检索所有 JSON 项目的“图库”:https : //pastebin.com/KnEwZzxd我尝试了很多解决方案,但我无法创建这个儿子的解码。我也在 pastebin 上发布了完整的代码。

{
"status": 200,
"data": {
    "date": "2018-07-29T00:00:00.300Z",
    "featured": [
        {
            "id": "5b56298d781e197186378f50",
            "name": "Sun Tan Specialist",
            "price": "1,500",
            "priceIcon": "vbucks",
            "priceIconLink": "https://image.fnbr.co/price/icon_vbucks.png",
            "images": {
                "icon": "https://image.fnbr.co/outfit/5b56298d781e197186378f50/icon.png",
                "png": "https://image.fnbr.co/outfit/5b56298d781e197186378f50/png.png",
                "gallery": "https://image.fnbr.co/outfit/5b56298d781e197186378f50/gallery.jpg",
                "featured": "https://image.fnbr.co/outfit/5b56298d781e197186378f50/featured.png"
            },
            "rarity": "epic",
            "type": "outfit",
            "readableType": "Outfit"
        },
        {
            "id": "5b562af2781e19db65378f5c",
            "name": "Rescue Paddle",
            "price": "800",
            "priceIcon": "vbucks",
            "priceIconLink": "https://image.fnbr.co/price/icon_vbucks.png",
            "images": {
                "icon": "https://image.fnbr.co/pickaxe/5b562af2781e19db65378f5c/icon.png",
                "png": "https://image.fnbr.co/pickaxe/5b562af2781e19db65378f5c/png.png",
                "gallery": "https://image.fnbr.co/pickaxe/5b562af2781e19db65378f5c/gallery.jpg",
                "featured": false
            },
            "rarity": "rare",
            "type": "pickaxe",
            "readableType": "Pickaxe"
        }
    ],
    "daily": [
        {
            "id": "5ab1723e5f957f27504aa502",
            "name": "Rusty Rider",
            "price": "1,200",
            "priceIcon": "vbucks",
            "priceIconLink": "https://image.fnbr.co/price/icon_vbucks.png",
            "images": {
                "icon": "https://image.fnbr.co/glider/5ab1723e5f957f27504aa502/icon.png",
                "png": "https://image.fnbr.co/glider/5ab1723e5f957f27504aa502/png.png",
                "gallery": "https://image.fnbr.co/glider/5ab1723e5f957f27504aa502/gallery.jpg",
                "featured": "https://image.fnbr.co/glider/5ab1723e5f957f27504aa502/featured.png"
            },
            "rarity": "epic",
            "type": "glider",
            "readableType": "Glider"
        },
        {
            "id": "5b0e944bdb94f1a4bbc0a8e4",
            "name": "Rambunctious",
            "price": "500",
            "priceIcon": "vbucks",
            "priceIconLink": "https://image.fnbr.co/price/icon_vbucks.png",
            "images": {
                "icon": "https://image.fnbr.co/emote/5b0e944bdb94f1a4bbc0a8e4/icon.png",
                "png": "https://image.fnbr.co/emote/5b0e944bdb94f1a4bbc0a8e4/png.png",
                "gallery": "https://image.fnbr.co/emote/5b0e944bdb94f1a4bbc0a8e4/gallery.jpg",
                "featured": false
            }
    ]
}
}
黑镜

除了发布JSON代码本身之外,实际尝试展示您如何尝试对其进行解码也是有用的^_________^。

无论如何,解决这个问题的最好方法是使用自定义结构和Decodable Protocol处理JSON响应。

从您开始,JSON您将获得两个值:

/// The Initial Response From The Server
struct Response: Decodable {
    let status: Int
    let data: ResponseData

}

然后我们将“数据”映射到一个名为的结构体ResponseData

/// The Data Object
struct ResponseData: Decodable{
    let date: String
    let featured: [Product]
    let daily: [Product]
}

在这个我们有两个variables包含一个相同的数组struct,我称之为Product

/// The Product Structure
struct Product: Decodable{
    let id: String
    let name: String
    let price: String
    let priceIcon: String
    let priceIconLink: String
    let images: ProductImages
    let rarity: String
    let type: String
    let readableType: String
}

在其中variable我们有一个dictionary(图像),然后我们将其映射到另一个struct

/// The Data From The Product Images Dictionary
struct ProductImages: Decodable{
    let icon: String
    let png: String
    let gallery: String

    ///The Featured Variable For The Product Images Can Contain Either A String Or A Boolean Value
    let featured: FeaturedType

}

您对 , 的问题ProductImages是,该功能var有时包含 aString但在其他情况下它包含一个Bool值。因此,我们需要创建一个自定义结构来处理这个解码,以确保我们总是得到一个String(我可能没有这样做,所以如果有人有更好的解决方案,请说出来):

/// Featured Type Returns A String Of Either The Boolean Value Or The Link To The JPG
struct FeaturedType : Codable {

    let formatted: String

    init(from decoder: Decoder) throws {

        let container =  try decoder.singleValueContainer()

        do {
            //1. If We Get A Standard Response We Have A String
            let stringResult = try container.decode(String.self)
            formatted = stringResult
        } catch {
            //2. On Occassions We Get An Bool
            let boolResult = try container.decode(Bool.self)
            formatted = String(boolResult)

        }
    }
}

现在这是你的基本结构,JSON所以现在你需要处理它。在这个例子中,我从 加载JSONMainBundle因为我没有实际的URL.

/// Loads & Decodes The JSON File
func retreiveJSON(){

    //1. Load The JSON File From The Main Bundle
    guard let jsonURL = Bundle.main.url(forResource: "sample", withExtension: ".json") else { return }

    do{
        //2. Get The Data From The URL
        let data = try Data(contentsOf: jsonURL)

        //3. Decode The JSON
        let jsonData = try JSONDecoder().decode(Response.self, from: data)

        //4. Extract The Data
        extractDataFrom(jsonData)

    }catch{
        print("Error Processing JSON == \(error)")
    }
}

在上面的函数中,您会注意到我正在调用该函数extractDataFrom()该函数允许您对数据执行所需的操作:

/// Extracts The Daily & Featured Products From The JSON
///
/// - Parameter jsonData: Response
func extractDataFrom(_ jsonData: Response){

    //1. Get The Daily Products
    let dailyProducts = jsonData.data.daily

    dailyProducts.forEach { (product) in

        print(product.id)
        print(product.name)
        print(product.price)
        print(product.priceIcon)
        print(product.priceIconLink)
        print(product.images)
        print(product.rarity)
        print(product.type)
        print(product.readableType)
    }


    //2. Get The Featured Products
    let featuredProducts = jsonData.data.featured

    featuredProducts.forEach { (product) in

        print(product.id)
        print(product.name)
        print(product.price)
        print(product.priceIcon)
        print(product.priceIconLink)
        print(product.images)
        print(product.rarity)
        print(product.type)
        print(product.readableType)
    }
}

如果您想保存这些数据,那么您需要做的就是在类声明下添加以下变量,例如:

var featuredProducts = [Product]()
var dailyProducts = [Product]()

并在 extractDataFrom() 函数中更改:

 let dailyProducts
 let featuredProducts

至:

dailyProducts = jsonData.data.daily
featuredProducts = jsonData.data.featured

请注意,这是一个非常粗略的示例,如上所述,我可能没有正确处理“特色”变量。

希望能帮助到你...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章