JS 对象到 Swift 结构
Posted
技术标签:
【中文标题】JS 对象到 Swift 结构【英文标题】:JS Object to Swift Struct 【发布时间】:2019-04-01 10:26:42 【问题描述】:我在将数据(类似于我从端点获取的 JSON)解析为 Swift 结构时遇到了困难。我从端点获得的数据似乎不是有效的 JSON(至少不是所有的数据都在查看 object = (...) 的结构),所以我无法解码 @987654322 @。
我应该用另一种方式解析它吗?非常感谢任何建议
我准备的结构是:
struct Response:Codable
let message:String?
let list:ListStruct?
let error:Bool?
struct ListStruct:Codable
let object1:[Object1]?
let object2:[Object2]?
let object3:[Object3]?
struct Object1:Codable
id:Int?
name:String?
...
我从端点获得的数据示例:
["message": <null>, "list":
object1 = (
id = 1;
name = "testing1";
);
object2 = (
files = (
);
id = 1;
name = "testing2-1";
photos = (
);
,
files = (
);
id = 2;
name = "testing2-2";
photos = (
);
systemId = 8;
);
object3 = (
id = 6;
name = "testing3-1";
,
id = 13;
name = "testing3-2";
);
, "error": 0]
编辑
我是如何尝试解码的:
if let result = try JSONDecoder().decode(Response?.self, from: "\(response!)".data(using: .utf8)! )
print("\(result)")
我得到的错误:
Error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 6." UserInfo=NSDebugDescription=No string key for value in object around character 6.)))
【问题讨论】:
粘贴你的json代码here. 这就是JSON
在Xcode console
上的样子,这没有问题。告诉我们您在decoding
时遇到的错误。使用@dahiya_boy 的上述链接生成您的模型类。
输出既不是 JSON 也不是集合类型 description。两者兼而有之。
“我从端点获得的数据示例:”:你在哪里打印的?如果它真的是 JSON,似乎已经通过 JSONSerialization 解析,并混合了 Swift Dictionary,以及“Objective-C”NSArray 和 NSDictionary。 response
到底是什么?你能显示你得到它的线条吗?我会说你使用的方法已经在解析它了。
错误的原因很可能是无意义的字符串插值"\(response!)"
当然不会产生有效的JSON。 response
来自哪里?
【参考方案1】:
很可能,您通过使用字符串插值创建传递了错误的数据对象。如果response
类型为Data
,则无需在下一行重新创建它,
if let result = try JSONDecoder().decode(Response?.self, from: "\(response!)".data(using: .utf8)! )
尝试按原样传递response
。如下图,
if let result = try JSONDecoder().decode(Response?.self, from: response!)
这是一个完整的可测试示例,其中使用有问题的json
创建了正确的数据对象,并且Response
中的error
类型从Optional
Bool
更改为Int
,
struct Response:Codable
let message:String?
let list:ListStruct?
let error: Int?
struct ListStruct: Codable
let object1:[Object1]?
let object2:[Object2]?
let object3:[Object3]?
struct Object1: Codable
var id:Int?
var name:String?
struct Object2: Codable
var id:Int?
var name:String?
var systemId: Int?
struct Object3: Codable
var id:Int?
var name:String?
用法:
let data = """
"message": null,
"list":
"object1": [
"id": 1,
"name": "testing1"
],
"object2" : [
"files" : [
],
"id" : 1,
"name" : "testing2-1",
"photos" : [
]
,
"files" : [
],
"id" : 2,
"name" : "testing2-2",
"photos" : [
],
"systemId" : 8
],
"object3" : [
"id" : 6,
"name" : "testing3-1",
,
"id" : 13,
"name" : "testing3-2",
]
,
"error": 0
""".data(using: .utf8)!
if let result = try! JSONDecoder().decode(Response?.self, from: data)
result.list?.object1?.forEach( obj in
print(obj.name)
)
result.list?.object2?.forEach( obj in
print(obj.name)
)
result.list?.object3?.forEach( obj in
print(obj.name)
)
输出:
Optional("testing1")
Optional("testing2-1")
Optional("testing2-2")
Optional("testing3-1")
Optional("testing3-2")
【讨论】:
以上是关于JS 对象到 Swift 结构的主要内容,如果未能解决你的问题,请参考以下文章
将 JSON 数据从 Parse Cloud Code 返回到 Swift 中的可解码结构
将 DataSnapshot 转换为自定义结构对象 - Swift 4