标签: decodable

Swift 4 Decodable - 将JSON对象解码为`Data`

我有以下数据结构:

{
    "type": "foo"
    "data": { /* foo object */ }
}
Run Code Online (Sandbox Code Playgroud)

这是我的解码它的类:

final public class UntypedObject: Decodable {

    public var data: Data

    enum UntypedObjectKeys: CodingKey {
        case data
    }

    required public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: UntypedObjectKeys.self)

        self.data = try values.decode(Data.self, forKey: .data)
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在获取这样的对象数组,这就是我解码它的方式:

let decoder = JSONDecoder()
let objectList = try decoder.decode([UntypedObject].self, from: data)
Run Code Online (Sandbox Code Playgroud)

但是我在控制台中收到此错误:

typeMismatch(Swift.Array,Swift.DecodingError.Context(codingPath:[Foundation.(_ JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue:"Index 0",intValue:Optional(0)),Playground_Sources.UntypedObject.UntypedObjectKeys.data],debugDescription:"期望解码数组但是找到了一个字典.",underlyingError:nil))

所以问题是可以将正确的JSON对象解码为Data类型属性,如果是这样的话 - 我该如何实现呢?

swift4 decodable

5
推荐指数
1
解决办法
1191
查看次数

在继承中使用Decodable会引发异常

我正在使用Rest API服务,在该服务中,响应分为基本响应,所有其他响应都从该继承。

我正在尝试使用Decoder接口为响应模型类构建相同的结构。

但是我在解码继承的类时遇到问题。

我试图解决此问题: 在带有继承的Swift 4中使用Decodable

但是没有运气。

这是初始结构:

class LoginResponse: BaseResponse{

    var Message: String?

    private enum CodingKeys: String, CodingKey{
        case Message
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        Message = try container.decode(String.self, forKey: .Message)
        let superDecoder = try container.superDecoder()
        try super.init(from: superDecoder)
    }
}

class BaseResponse: Decodable {

    var Status: Int?

    private enum CodingKeys: String, CodingKey{
        case Status
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self) // This …
Run Code Online (Sandbox Code Playgroud)

swift decodable

5
推荐指数
1
解决办法
1637
查看次数

Swift 4 JSON 值为空

我在优雅地处理这个错误时遇到了问题debugDescription: "Expected String value but found null instead." 我知道在我的结构中符合Codable,我的存储属性需要声明为可选字符串,正如我在这篇文章中读到

我试过了,仍然出现错误。我还在那篇文章中读到,我还可以自定义解码器以将 nil 替换为空字符串。我不知道如何做到这一点。

这是我的代码:

struct Discover: Codable {
    var page: Int
    var totalResults: Int
    var totalPages: Int
    var results: [DiscoverResults]

     enum CodingKeys: String, CodingKey {
        case page
        case totalResults = "total_results"
        case totalPages = "total_pages"
        case results = "results"
    }

}

struct DiscoverResults {
    var title: String
    var releaseDate: String
    var posterPath: String?
    var id: Int
    var genreIds: [Int]
    var poster: UIImage?

     enum CodingKeys: String, …
Run Code Online (Sandbox Code Playgroud)

json ios swift4 codable decodable

5
推荐指数
0
解决办法
3107
查看次数

Swift Codable初始化

我想在Swift Coding / Encoding功能完成对JSON的解码后做一些初始化逻辑。

struct MyStruct: Codable {
    let id: Int 
    var name: String

    init() {
       name = "\(id) \(name)" 
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了编译器错误:

Return from initializer without initializing all stored properties
Run Code Online (Sandbox Code Playgroud)

这对我很清楚,因为init()希望我初始化所有属性。但是添加具有所有必需属性的init()并不能解决该问题,因为当Codable插入时,此初始化器不会被调用(!):

init(id: Int, name: String) {
    // This initializer is not called if Decoded from JSON!
    self.id = id 
    self.name = "\(id) \(name)" 
}
Run Code Online (Sandbox Code Playgroud)

然而,在解码完成之后,是否有一种方法可以执行一些初始化逻辑,而无需为每个属性手动进行所有解码?因此无需每次都执行init(from decoder: Decoder)。在这个简短的示例中,我只有两个简单的属性,但是生产代码包含数千个属性。

谢谢。

json swift codable decodable

5
推荐指数
2
解决办法
8106
查看次数

在SWIFT 4中解析嵌套JSON

我目前正在使用SWIFT 4中的Decodable解析JSON.

JSON格式如下:

  {
  "autopayout_from": "1.010",
  "earning_24_hours": "9.74731104",
  "error": false,
  "immature_earning": 0.635593030875,
  "last_payment_amount": "1.91238210",
  "last_payment_date": "Mon, 26 Feb 2018 15:08:02 GMT",
  "last_share_date": "Mon, 26 Feb 2018 16:16:01 GMT",
  "payout_daily": false,
  "payout_request": false,
  "total_hashrate": 109006.86,
  "total_hashrate_calculated": 143855.75,
  "transferring_to_balance": 0.2281390807,
  "wallet": "0xbb76fc2ce36a19da28fd713e350a42f1023e2f7f",
  "wallet_balance": "0.49556201",
  "workers": {
    "10003": {
      "alive": false,
      "hashrate": 0.0,
      "hashrate_below_threshold": false,
      "hashrate_calculated": 0.0,
      "last_submit": "Mon, 26 Feb 2018 13:23:16 GMT",
      "second_since_submit": 10612,
      "worker": "10003"
    },
    "100151": {
      "alive": false,
      "hashrate": 0.0,
      "hashrate_below_threshold": false,
      "hashrate_calculated": 0.0,
      "last_submit": "Mon, 26 Feb …
Run Code Online (Sandbox Code Playgroud)

json nested swift codable decodable

5
推荐指数
1
解决办法
3728
查看次数

Swift:Codable - 提取单个编码密钥

我有以下代码来提取编码密钥中包含的JSON:

let value = try! decoder.decode([String:Applmusic].self, from: $0["applmusic"])
Run Code Online (Sandbox Code Playgroud)

这成功处理了以下JSON:

{
  "applmusic":{
    "code":"AAPL",
    "quality":"good",
    "line":"She told me don't worry",
}
Run Code Online (Sandbox Code Playgroud)

但是,无法使用以下编码密钥提取JSON applmusic:

{
  "applmusic":{
    "code":"AAPL",
    "quality":"good",
    "line":"She told me don't worry",
  },
  "spotify":{
    "differentcode":"SPOT",
    "music_quality":"good",
    "spotify_specific_code":"absent in apple"
  },
  "amazon":{
    "amzncode":"SPOT",
    "music_quality":"good",
    "stanley":"absent in apple"
  }
}
Run Code Online (Sandbox Code Playgroud)

数据模型applmusic,spotify并且amazon是不同的.但是,我只需要提取applmusic和省略其他编码密钥.

我的Swift数据模型如下:

public struct Applmusic: Codable {
    public let code: String
    public let quality: String
    public let line: String
}
Run Code Online (Sandbox Code Playgroud)

API以完整的JSON响应,我不能要求它只给我所需的字段.

如何只解码json的特定部分?看起来,这Decodable …

json ios swift codable decodable

5
推荐指数
1
解决办法
3717
查看次数

Codable:不符合协议'可解码'

无法理解为什么我的类不符合Codable请不要在我的情况下我不需要实现编码解码方法.

public class LCLAdvantagePlusJackpotCache: Codable {
    public let token: String
    public let amount: NSNumber
    public let member: Bool

    public init(token: String, amount: NSNumber, member: Bool) {
        self.token = token
        self.amount = amount
        self.member = member
    }

    enum CodingKeys: String, CodingKey {
        case token, amount, member
    }

}
Run Code Online (Sandbox Code Playgroud)

swift codable decodable

5
推荐指数
1
解决办法
3412
查看次数

如何使用“Decodable”对象在 Realm 中进行部分更新而不丢失数据?

我有一个 JSON-API,它返回Courses. 它们Courses都有主键CourseLocations。我认为使用 解析所有内容并使用 更新它CourseTypes会很棒。CodableRealm().add(_:update:)

一切都很好。当 API 不返回完整的对象时就会出现问题。

这么说吧。API“/types”返回下面的数组,它包含创建或更新对象所需的所有数据。

[
   { "id": "1", "name": "Type 1", "sessions": 10, "sessionTime": 120.0 },
   { "id": "2", "name": "Type 2", "sessions": 5, "sessionTime": 20.0 }
]
Run Code Online (Sandbox Code Playgroud)

但随后我调用另一个 API 方法“/courses”,它返回一个课程信息以及对象“类型”,但不是全部,只是它的idname

[
   {
     "id": "0013",
     "name": "Super cool course",
     "type": { "id": "2", "name": "Type 2" }
    }
]
Run Code Online (Sandbox Code Playgroud)

因此,当我为课程执行“add(_:update:)”时,我实际上更新了对象的所有值CourseType,而不仅仅是名称。结果,mysessionssessionTimeproperty 被设置为 0。

我该如何避免呢?

这里有一个类供参考。

class …
Run Code Online (Sandbox Code Playgroud)

realm swift decodable

5
推荐指数
0
解决办法
166
查看次数

预计会解码Int,但会找到一个数字

我在Swift 4.2中遇到了JSON解析的问题.以下是显示运行时错误的以下代码.

我的Json数据如下所示,我从服务器获得.

{
    code: 406,
    message: "Email Address already Exist.",
    status: 0
}
Run Code Online (Sandbox Code Playgroud)

我使用Codable来创建我的结构如下

struct Registration: Codable {
    var code: Int
    var status: Int
    private enum CodinggKeys: String, CodingKey {
        case code
        case status
    }
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            self.code = Int(try container.decode(String.self, forKey: .code))!
        } catch DecodingError.typeMismatch {
            let value = try container.decode(Double.self, forKey: .code)
            self.code = Int(value);
        }

        do {
            self.status = try container.decode(Int.self, forKey: .status)
        } …
Run Code Online (Sandbox Code Playgroud)

json ios codable decodable swift4.2

5
推荐指数
1
解决办法
3227
查看次数

Swift:正确解码不精确的十进制

我需要Decodable正确解码(协议)一个不精确的十进制值,从这个问题我了解如何正确处理十进制实例化,但是在解码时如何做到这一点?

如果尝试将任何数字初始化为字符串

if let value = try! container.decode(String.self, forKey: .d) {
    self.taxAmount = Decimal(string: value)
}
Run Code Online (Sandbox Code Playgroud)

我明白了Fatal Error: "Expected to decode String but found a number instead."

如果尝试将 130.43 初始化为十进制

if let value = try! container.decode(Decimal.self, forKey: .d) {
    //value.description is 130.43000000000002048
    self.d = Decimal(string: value.description)
    //making subtotal to be also 130.43000000000002048 and not 130.43
}
Run Code Online (Sandbox Code Playgroud)

解码时有什么方法可以使用这个构造函数吗?

  • NSDecimalNumber(string: "1.66")
  • NSDecimalNumber(value: 166).dividing(by: 100)
  • Decimal(166)/Decimal(100)
  • Decimal(sign: .plus, exponent: -2, significand: 166)

以下是我从外部服务收到的 JSON 的简化版本:

{
   "priceAfterTax": 150.00, …
Run Code Online (Sandbox Code Playgroud)

nsdecimalnumber swift decodable

5
推荐指数
1
解决办法
5915
查看次数

标签 统计

decodable ×10

swift ×7

codable ×6

json ×5

ios ×3

swift4 ×2

nested ×1

nsdecimalnumber ×1

realm ×1

swift4.2 ×1