标签: decodable

Swift Codable 将空 json 解码为 nil 或空对象

这是我的代码:

class LoginUserResponse : Codable {
    var result: String = ""
    var data: LoginUserResponseData?
    var mess: [String] = []
}

public class LoginUserResponseData : Codable {
    var userId = "0"
    var name = ""
}
Run Code Online (Sandbox Code Playgroud)

现在,调用服务器 API 我正在解析这样的响应(使用 Stuff 库来简化解析):

do {
    let loginUserResponse = try LoginUserResponse(json: string)
} catch let error {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

当我输入正确的密码时,我会得到这样的答案:

{"result":"success","data":{"userId":"10","name":"Foo"},"mess":["You're logged in"]}
Run Code Online (Sandbox Code Playgroud)

这很好,解析器工作正常。

提供错误密码时给出以下答案:

{"result":"error","data":{},"mess":["Wrong password"]}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,解析器失败了。它应该将数据设置为 nil,而是尝试将其解码为 LoginUserResponseData 对象。

我在使用改造的 Android 上使用相同的方法,它工作正常。我宁愿不想将所有字段都设为可选。

有没有办法让解析器将空的 json {} 视为 nil?或者将 LoginUserResponseData 设为非可选并且它只有默认值?我知道我可以为此创建一个自定义解析器,但我有大量这样的请求,它需要太多的额外工作。

ios swift codable decodable

7
推荐指数
2
解决办法
2万
查看次数

预期解码 Dictionary<String, Any> 但发现了字符串/数据

我正在使用可文档协议,但遇到此错误:

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [MakeApp_v2.Params.(CodingKeys in _244BBB2F32A8C5CF3DB84B0C6A94B232).config, Swift._DictionaryCodingKey(stringValue: "table", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))
Run Code Online (Sandbox Code Playgroud)

这是我遇到错误的 JSON

{
  "callBackID" : "add1867f-6005-189c-bbb4-ff53202b0697",
  "config" : {
    "description" : "Welcome Page",
    "show-bottom-bar" : "",
    "css-page-align" : "",
    "footer" : { "show" : "", "object" : "bottom-bar" },
    "pageStyle" : "full-page",
    "sourceType" : "list",
    "title" : "Welcome Page",
    "header" : { "show" : true, "hide" : false, "object" : "top-bar" },
    "columns" : {},
    "objects" …
Run Code Online (Sandbox Code Playgroud)

json struct swift4 decodable

7
推荐指数
1
解决办法
8746
查看次数

Swift 4 Decodable:来自嵌套数组的struct

鉴于以下JSON文档,我想创建一个struct包含四个属性:filmCount(Int),year(Int),category(String)和actor(Actor数组).

{    
    "filmCount": 5,
    "year": 2018,
    "category": "Other",
    "actors":{  
        "nodes":[  
            {  
                "actor":{  
                    "id":0,
                    "name":"Daniel Craig"
                }
            },
            {  
                "actor":{  
                    "id":1,
                    "name":"Naomie Harris"
                }
            },
            {  
                "actor":{  
                    "id":2,
                    "name":"Rowan Atkinson"
                }
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

PlacerholderData是一个存储三个主要属性和actor列表的结构,这些属性应该从JSON对象nodesactors属性中的嵌套容器中检索.

PlacerholderData:

struct PlaceholderData: Codable {
    let filmCount: Int
    let year: Int
    let category: String
    let actors: [Actor]
}
Run Code Online (Sandbox Code Playgroud)

Actor.swift:

struct Actor: Codable {
    let id: Int
    let name: String
} …
Run Code Online (Sandbox Code Playgroud)

json swift codable decodable

7
推荐指数
1
解决办法
2301
查看次数

Swift Codable多种类型

我尝试解析返回json对象的api。我的问题是,在以下示例中,某些键有时是字符串,有时是类似键“ Value”的对象:

[
{
    "Description": null,
    "Group": "Beskrivning av enheten",
    "GroupDescription": null,
    "Id": "Description",
    "Name": "Mer om enheten",
    "Value": "Det finns möjlighet till parkering på gatorna runt om, men det är kantstenar och ganska branta backar för att komma upp till lekplatsen.\r\n\r\nUtanför själva lekplatsen finns en gungställning med en plan omväg in. Alla lekredskap står i sandytor, det finns många kanter. Runt hela lekplatsen går ett staket med öppningar i olika riktningar."
},
{
    "Description": null,
    "Group": "Bilder och film", …
Run Code Online (Sandbox Code Playgroud)

swift codable decodable

7
推荐指数
2
解决办法
2244
查看次数

致命错误:Dictionary <String,Any>不符合Decodable,因为Any不符合Decodable

我正在尝试使用swift 4来解析本地json文件:

{
    "success": true,
    "lastId": null,
    "hasMore": false,
    "foundEndpoint": "https://endpoint",
    "error": null
}
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的功能:

    func loadLocalJSON() {

        if let path = Bundle.main.path(forResource: "localJSON", ofType: "json") {
            let url = URL(fileURLWithPath: path)

            do {
                let data  = try Data(contentsOf: url)
                let colors = try JSONDecoder().decode([String: Any].self, from: data)
                print(colors)
            }
            catch { print("Local JSON not loaded")}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我一直收到错误:

致命错误:Dictionary不符合Decodable,因为Any不符合Decodable.

我尝试在此stackoverflow页面上使用"AnyDecodable"方法:如何在Swift 4可解码协议中解码具有JSON字典类型的属性, 但它跳转到'catch'语句: catch { print("Local JSON not loaded")使用时.有谁知道如何在Swift 4中解析这个JSON数据?

json ios swift swift4 decodable

6
推荐指数
1
解决办法
1685
查看次数

Swift Codable:如何将顶级数据编码到嵌套容器中

我的应用程序使用一个返回 JSON 的服务器,如下所示:

{
    "result":"OK",
    "data":{

        // Common to all URLs
        "user": {
            "name":"John Smith" // ETC...
        },

        // Different for each URL
        "data_for_this_url":0
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,特定于 URL 的信息与通用user词典存在于同一词典中。

目标:

  1. 将此 JSON 解码为类/结构。
    • 因为user很常见,我希望它位于顶级类/结构中。
  2. 编码为新格式(例如 plist)。
    • 我需要保留原始结构。(即data从顶级user信息和子对象的信息重新创建字典)

问题:

重新编码数据时,我无法将user字典(来自顶级对象)和特定于 URL 的数据(来自子对象)写入编码器。

要么user覆盖其他数据,要么其他数据覆盖user. 我不知道如何将它们结合起来。

这是我到目前为止所拥有的:

// MARK: - Common User
struct User: Codable {
    var name: String?
}

// MARK: - Abstract Response
struct ApiResponse<DataType: Codable>: Codable …
Run Code Online (Sandbox Code Playgroud)

ios swift codable decodable encodable

6
推荐指数
1
解决办法
5600
查看次数

iOS Swift Decodable:错误:无法为没有参数的类型调用初始化程序

初始化结构时出现错误,请参见下面的屏幕截图。调试后,我发现在结构中包含review变量会产生问题。我不知道我在做什么错。谁能帮我吗?

Tx

我正在复制代码,以防万一您需要尝试一下

import UIKit

struct RootValue : Decodable {
    private enum CodingKeys : String, CodingKey {
        case success = "success"
        case content = "data"
        case errors = "errors"
    }
    let success: Bool
    let content : [ProfileValue]
    let errors: [String]
}

struct ProfileValue : Decodable {
    private enum CodingKeys : String, CodingKey {
        case id = "id"
        case name = "name"
        case review = "review" // including this gives error
    }

    var id: Int = 0
    var name: String = …
Run Code Online (Sandbox Code Playgroud)

ios swift swift4 decodable

6
推荐指数
1
解决办法
8662
查看次数

如何从iOS Swift Codable的API响应中通知或打印模型类上缺少的键?

我从API收到一个JSON响应,如下所示:

先前的JSON响应:

[
  {
    "EmployeeId": 711,
    "FirstName": "Steve",
    "LastName": "Jobs"
  },
  {
    "EmployeeId": 714,
    "FirstName": "John",
    "LastName": "Doe"
  }
]
Run Code Online (Sandbox Code Playgroud)

和相同的模型类具有以下代码

class EmployeeModel: Codable {

    let EmployeeId: Int?
    let FirstName: String?
    let LastName: String?
}
Run Code Online (Sandbox Code Playgroud)

Swift Codable解析工作正常

do {
    let decodedResponse = try JSONDecoder().decode([EmployeeModel].self, from: response.rawData())
    print(decodedResponse)

} catch let jsonErr {
    print(jsonErr.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)

但是现在

最新的JSON响应

从API更改,并添加了一个MiddleName键作为响应,请参见以下屏幕截图,并且它与Swift Codable代码也可以正常工作。 在此处输入图片说明

但是,如何从iOS Swift 5的API的JSON响应中获得通知或打印MiddleName密钥的信息呢?

更新问题

根据@ CZ54在下面提供的答案,解决方案可以正常工作,但无法检查是否缺少另一个派生类。例如:

在此处输入图片说明

// MARK:- LoginModel
class LoginModel: Codable {

    let token: String?
    let …
Run Code Online (Sandbox Code Playgroud)

json ios swift codable decodable

6
推荐指数
1
解决办法
164
查看次数

Swift 5 默认可解码实现,只有一个例外

有没有办法保留 Swift 对 Decodable 类的默认实现,其中只有 Decodable 对象但有一个例外?例如,如果我有一个这样的结构/类:

struct MyDecodable: Decodable {
   var int: Int
   var string: String
   var location: CLLocation
}
Run Code Online (Sandbox Code Playgroud)

我想使用默认解码intstringlocation自己解码。所以在init(from decoder:)我想有这样的事情:

required init(from decoder: Decoder) throws {
    <# insert something that decodes all standard decodable properties #>

    // only handle location separately
    let container = try decoder.container(keyedBy: CodingKeys.self)
    location = <# insert custom location decoding #>
}
Run Code Online (Sandbox Code Playgroud)

ios swift codable decodable swift5

6
推荐指数
1
解决办法
376
查看次数

Swift Decodable - 如何解码经过 base64 编码的嵌套 JSON

我正在尝试解码来自第三方 API 的 JSON 响应,其中包含已进行 base64 编码的嵌套/子 JSON。

人为的示例 JSON

{
   "id": 1234,
   "attributes": "eyAibmFtZSI6ICJzb21lLXZhbHVlIiB9",  
}
Run Code Online (Sandbox Code Playgroud)

PS"eyAibmFtZSI6ICJzb21lLXZhbHVlIiB9"{ 'name': 'some-value' }base64 编码的。

我目前有一些代码可以对此进行解码,但不幸JSONDecoder()的是init,为了这样做,我必须重新实例化一个额外的内部,这并不酷......

人为的示例代码


struct Attributes: Decodable {
    let name: String
}

struct Model: Decodable {

    let id: Int64
    let attributes: Attributes

    private enum CodingKeys: String, CodingKey {
        case id
        case attributes
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        self.id = try container.decode(Int64.self, forKey: .id)

        let encodedAttributesString = …
Run Code Online (Sandbox Code Playgroud)

swift codable decodable

6
推荐指数
1
解决办法
300
查看次数

标签 统计

decodable ×10

swift ×9

codable ×7

ios ×6

json ×4

swift4 ×3

encodable ×1

struct ×1

swift5 ×1