我正在使用一个外部框架来显示消息列表和详细信息屏幕。
我们无法修改的框架内部消息模型:
public struct Message: Decodable, Encodable {
public var id: String?
public var title: String?
public var subTitle: String?
public var status: String?
}
我们的API响应:
{
"data":{
"custId":"1234",
"type":"premium",
"totalCount":"100",
"msgList":[
{
"id":"1",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
},
{
"id":"2",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
}
],
"categoryCount":"50"
}
}
如何从JSON响应中提取msgList
数组并解码为Message
模型。
有点像只传递list
data / json:
let responseMessage =试试JSONDecoder()。decode([Message.self],来自: 列表)
感谢您的帮助和建议!
谢谢
答案 0 :(得分:0)
您必须创建有效负载结构。
struct Data: Decodable {
struct Payload: Decodable {
let msgList: [Message]
}
let data: Payload
}
使用JSONDecoder解码JSON。
let responseMessage = try JSONDecoder().decode([Message.self], from: list)
messageList可以使用:responseMessage.data.msgList
答案 1 :(得分:0)
这应该很容易,但是除非您要开始覆盖init(from decoder:)
方法并手动执行一些操作,否则您需要解码整个JSON对象。
尝试仅从JSON中提取出消息数组将比其值得的麻烦。
import UIKit
let jsonData = """
{
"data":{
"custId":"1234",
"type":"premium",
"totalCount":"100",
"msgList":[
{
"id":"1",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
},
{
"id":"2",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
}
],
"categoryCount":"50"
}
}
""".data(using: .utf8)
struct Root: Decodable {
let data: Customer
}
struct Customer: Decodable {
let custId: String
let type: String
let totalCount: String
let msgList: [Message]
}
public struct Message: Decodable, Encodable {
public var id: String?
public var title: String?
public var subTitle: String?
public var status: String?
}
do {
let result = try JSONDecoder().decode(Root.self, from: jsonData!)
print(result)
} catch {
print(error)
}
您可以访问以下消息:
let messages = result.data.msgList
答案 2 :(得分:0)
应该看起来像这样:
// MARK: - Root
struct Root: Codable {
let data: DataClass
}
// MARK: - DataClass
struct DataClass: Codable {
let custID, type, totalCount: String
let msgList: [MsgList]
let categoryCount: String
enum CodingKeys: String, CodingKey {
case custID = "custId"
case type, totalCount, msgList, categoryCount
}
}
// MARK: - MsgList
struct MsgList: Codable {
let id, title, subTitle, status: String
}
然后加载您的数据:
let list: [String : Any] = [:] // load data accordingly...
if let responseMessage = try JSONDecoder().decode(Root.self, from: list)
{
// responseMessage.data.msgList
}
类名只是一个例子,请随时对它们进行重命名。
答案 3 :(得分:0)
您可以尝试
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let str = """
{
"data":{
"custId":"1234",
"type":"premium",
"totalCount":"100",
"msgList":[
{
"id":"1",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
},
{
"id":"2",
"title":"Main Title",
"subTitle":"Sub title",
"status":"R"
}
],
"categoryCount":"50"
}
}
"""
do {
let res = try JSONDecoder().decode(Root.self, from:Data(str.utf8))
print(res.list)
}
catch {
print(error)
}
}
}
struct Root : Decodable {
let list : [Message]
struct AnyCodingKey : CodingKey {
var stringValue: String
var intValue: Int?
init(_ codingKey: CodingKey) {
self.stringValue = codingKey.stringValue
self.intValue = codingKey.intValue
}
init(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
var con = try! decoder.container(keyedBy: AnyCodingKey.self)
con = try! con.nestedContainer(keyedBy: AnyCodingKey.self, forKey: AnyCodingKey(stringValue:"data"))
let res = try! con.decode([Message].self, forKey: AnyCodingKey(stringValue:"msgList"))
self.list = res
}
}
struct Message: Codable {
let id,title,subTitle,status: String?
}