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. 这就是JSONXcode 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 中的可解码结构

Swift 结构到 NSData 并返回

在 Swift 中创建类和结构来表示 JSON 对象

将 DataSnapshot 转换为自定义结构对象 - Swift 4

在 Swift 中,如何在由结构对象数组组成的字典中进行搜索?

数据结构 AOV网的关键路径(Swift面向对象版)