【发布时间】:2021-12-31 11:45:45
【问题描述】:
我有一个本地 json 并创建了可以解析和获取数据的数据模型,我想从数据模型创建一个视图模型以在视图控制器中使用任何建议如何使用 swift 高阶函数。
JSON:
{
"segment": {
"user1": {
"banners": {
"order": 1,
"items": [1, 3, 4]
},
"products": {
"order": 2,
"items": [1, 2, 3, 4]
}
},
"user2": {
"banners": {
"order": 2,
"items": [4, 3]
},
"products": {
"order": 1,
"items": [2, 3, 4]
}
}
},
"productsList": [{
"productId": 1,
"title": "Title of the product",
"description": "Desciprtion of the product"
}, {
"productId": 2,
"title": "Title of the product",
"description": "Desciprtion of the product"
}, {
"productId": 3,
"title": "Title of the product",
"description": "Desciprtion of the product"
}, {
"productId": 4,
"title": "Title of the product",
"description": "Desciprtion of the product"
}]
}
数据模型::
struct dataModel : Codable {
let segment : Segment?
let productsList : [ProductsList]?
enum CodingKeys: String, CodingKey {
case segment = "segment"
case productsList = "productsList"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
segment = try values.decodeIfPresent(Segment.self, forKey: .segment)
productsList = try values.decodeIfPresent([ProductsList].self, forKey: .productsList)
}
}
struct Banners : Codable {
let order : Int?
let items : [Int]?
enum CodingKeys: String, CodingKey {
case order = "order"
case items = "items"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
order = try values.decodeIfPresent(Int.self, forKey: .order)
items = try values.decodeIfPresent([Int].self, forKey: .items)
}
}
struct Products : Codable {
let order : Int?
let items : [Int]?
enum CodingKeys: String, CodingKey {
case order = "order"
case items = "items"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
order = try values.decodeIfPresent(Int.self, forKey: .order)
items = try values.decodeIfPresent([Int].self, forKey: .items)
}
}
struct ProductsList : Codable {
let productId : Int?
let title : String?
let description : String?
enum CodingKeys: String, CodingKey {
case productId = "productId"
case title = "title"
case description = "description"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
productId = try values.decodeIfPresent(Int.self, forKey: .productId)
title = try values.decodeIfPresent(String.self, forKey: .title)
description = try values.decodeIfPresent(String.self, forKey: .description)
}
}
struct Segment : Codable {
let user1 : User1?
let user2 : User1?
enum CodingKeys: String, CodingKey {
case user1 = "user1"
case user2 = "user2"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
user1 = try values.decodeIfPresent(User1.self, forKey: .user1)
user2 = try values.decodeIfPresent(User1.self, forKey: .user2)
}
}
struct User1 : Codable {
let banners : Banners?
let products : Products?
enum CodingKeys: String, CodingKey {
case banners = "banners"
case products = "products"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
banners = try values.decodeIfPresent(Banners.self, forKey: .banners)
products = try values.decodeIfPresent(Products.self, forKey: .products)
}
}
在视图模型中,每个用户都需要一个具有以下条件的部分数组。
- 部分必须基于 json 中的 order 键放置,例如,如果 order 为 1,那么它应该是用户数组中的第一个元素,而 2 在某种意义上它应该是用户数组中的第二个元素。
- items 数组表示 productsList 数组中的 productId,如果 items 数组有 3 则在 user 数组中应该附加 prodouctId:3。李>
在以上两个条件下,如何为 user1 和 user2 创建两个数组。以上面的 json 为例,它应该返回如下。
user1 = [<banners items products>, <products items products>] //Based on order key sorting in array.
user2 = [< products items products>, < banners items products>] //Based on order key sorting in array.
如下创建的 ViewModel 可以从 viewDidLoad 调用 viewModel,它应该为每个用户返回数据。任何人都可以建议在上述条件下执行此操作的正确方法我花了很多时间来做它没有按预期工作。
struct viewModel {
func getUser1Data() -> []{ ///As per json should return banners items as first element and then products items
}
func getUser2Data() -> [] { ///As per json should return products items as first element and then banners items
}
}
struct User {
var title: String?
var description: String?
}
获取和解析 json 的函数。
func getModelFromJson(fileName: String) -> dataModel? {
let decoder = JSONDecoder()
let url = Bundle.main.url(forResource: fileName, withExtension: "json")
let data = try? Data(contentsOf: url!)
do {
let result = try decoder.decode(dataModel.self, from: data!)
return result
} catch {
print(error)
}
return nil
}
【问题讨论】:
-
只有两个用户吗?
-
是的,只有用户。
标签: ios swift objective-c xcode jsondecoder