标签: codable

Swift可解码可选键

(这是此问题的后续跟进:使用具有多个键的可解码协议.)

我有以下Swift代码:

let additionalInfo = try values.nestedContainer(keyedBy: UserInfoKeys.self, forKey: .age)
age = try additionalInfo.decodeIfPresent(Int.self, forKey: .realage)
Run Code Online (Sandbox Code Playgroud)

我知道如果我使用decodeIfPresent并且没有该属性,如果它是一个可选变量,它仍将正确处理它.

例如,以下JSON使用上面的代码解析它.

{
    "firstname": "Test",
    "lastname": "User",
    "age": {"realage": 29}
}
Run Code Online (Sandbox Code Playgroud)

以下JSON也适用.

{
    "firstname": "Test",
    "lastname": "User",
    "age": {"notrealage": 30}
}
Run Code Online (Sandbox Code Playgroud)

但以下不起作用.

{
    "firstname": "Test",
    "lastname": "User"
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能使所有3个例子都有效?是否有类似的东西decodeIfPresentnestedContainer

json ios swift swift4 codable

13
推荐指数
2
解决办法
9811
查看次数

如何使用Swift Codable处理部分动态JSON?

我有一些通过websocket连接进入的JSON消息.

// sample message
{
  type: "person",
  data: {
    name: "john"
  }
}

// some other message
{
  type: "location",
  data: {
    x: 101,
    y: 56
  }
}
Run Code Online (Sandbox Code Playgroud)

如何使用Swift 4和Codable协议将这些消息转换为正确的结构?

在Go中我可以做类似的事情:"嘿,此刻我只关心这个type领域而我对其余部分(data部分)不感兴趣." 它看起来像这样

type Message struct {
  Type string `json:"type"`
  Data json.RawMessage `json:"data"`
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到Data的那样json.RawMessage,可以在以后解析.这是一个完整的示例https://golang.org/pkg/encoding/json/#example_RawMessage_unmarshal.

我可以在Swift中做类似的事情吗?喜欢(尚未尝试过)

struct Message: Codable {
  var type: String
  var data: [String: Any]
}
Run Code Online (Sandbox Code Playgroud)

然后switchtype将字典转换为适当的结构.那会有用吗?

ios swift codable

13
推荐指数
1
解决办法
2487
查看次数

得到这个错误:nw_protocol_get_quic_image_block_invoke dlopen libquic failed

我试图连接我的 API 数据以在单元格中查看它,但似乎我无法得到我的响应,而且总是== nil 下面的代码描述了 Country.SWIFT // Model.SWIFT // Response.SWIFT,它显示了如何我可以使用 Codable 获取 JSON 响应吗? CountryCell.SWIFT 展示了我如何使用它来调用 API API 图像的链接:

图片

国家.SWIFT

struct Country: Decodable {
    
    var CountryName = ""
    var CountryImage = ""
    var objectId = ""


// MARK: - Coding Keys
enum CodingKeys: String, CodingKey {
    case CountryName = "CountryName"
    case CountryImage = "CountryImage"
    case objectId = "objectId"
}

//MARK: - Json Decoder

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

json ios swift codable decodable

13
推荐指数
1
解决办法
6151
查看次数

可解码 - 继承阻止解码器init合成

我有以下Swift 4 Codable类,它继承自Realm的Object类型:

final class SearchResult: RealmSwift.Object, Codable {
    @objc dynamic var name: String = ""
    @objc dynamic var region: String = ""

    enum CodingKeys: String, CodingKey {
        case name = "name"
        case region = "region"
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的期望是该init(from decoder: Decoder)方法被合成,所以我不必自己实现它,这是一个巨大的便利.但是,不实现这会产生以下编译器错误:

super.init isn't called on all paths before returning from initializer

有三种方法可以摆脱编译器错误,但没有一种方法是好的:

  1. 实现一个init(from decoder: Decoder)只调用的空方法super.init().这似乎阻止了合成,意味着没有任何实际解码,因为它只是一个空方法.

  2. init(from decoder: Decoder)手动实现整个方法.这有效,但现在使用的乐趣Codable几乎消失了.

  3. 删除所有与Realm相关的代码.现在Codable按预期工作,但是,现在我不能再使用Realm了.

这对我来说似乎是一个Swift错误,因为它应该检测到init(from decoder: Decoder)实际上是在实现,而不是手动执行.

我不知道的任何建议或解决方法?

realm swift swift4 codable

12
推荐指数
1
解决办法
1102
查看次数

如何在可编码结构中使用计算属性(swift)

我创建了一个"可编码"结构来序列化数据集并将其编码为Json.除了计算属性没有显示在json字符串中之外,一切都工作得很好.如何在编码阶段包含计算属性.

例如:

struct SolidObject:Codable{

    var height:Double                      = 0
    var width:Double                       = 0
    var length:Double                      = 0

    var volume:Double {
        get{
            return height * width * length
        }
    }
}

var solidObject = SolidObject()
solidObject.height = 10.2
solidObject.width = 7.3
solidObject.length = 5.0

let jsonEncoder = JSONEncoder()
do {
    let jsonData = try jsonEncoder.encode(solidObject)
    let jsonString = String(data: jsonData, encoding: .utf8)!
    print(jsonString)
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

打印出"{"宽度":7.2999999999999998,"长度":5,"高度":10.199999999999999}"

我也很好奇有7.29999 ..而不是7.3但我的主要问题是"我怎么能包括"音量"这个json字符串呢?"?

json ios swift computed-properties codable

12
推荐指数
1
解决办法
2690
查看次数

Swift 4:使用Codable`通用参数'T'无法推断

我收到以下错误:

Generic parameter 'T' could not be inferred

在线: let data = try encoder.encode(obj)

这是代码

import Foundation

struct User: Codable {
    var firstName: String
    var lastName: String
}

let u1 = User(firstName: "Ann", lastName: "A")
let u2 = User(firstName: "Ben", lastName: "B")
let u3 = User(firstName: "Charlie", lastName: "C")
let u4 = User(firstName: "David", lastName: "D")

let a = [u1, u2, u3, u4]

var ret = [[String: Any]]()
for i in 0..<a.count {
        let param = [
            "a" : a[i], …
Run Code Online (Sandbox Code Playgroud)

encoder swift swift4 xcode9 codable

12
推荐指数
1
解决办法
6929
查看次数

如何在swift 4 Codable中手动解码数组?

这是我的代码.但我不知道该如何设定价值.它必须手动完成,因为实际结构比这个例子稍微复杂一些.

有什么帮助吗?

struct Something: Decodable {
   value: [Int]

   enum CodingKeys: String, CodingKeys {
      case value
   }

   init (from decoder :Decoder) {
      let container = try decoder.container(keyedBy: CodingKeys.self)
      value = ??? // < --- what do i put here?
   }
}
Run Code Online (Sandbox Code Playgroud)

swift codable

11
推荐指数
3
解决办法
1万
查看次数

忽略Codable对象中的非Codable可选属性

当符合Codable协议时,我不能轻易跳过非Codable类的可选属性

Ride结构,我们要跳过的编码解码driver财产,只要把它nil解码时:

  struct Ride: Codable {

    public var number: String
    public var passenger: Passenger? // Codable conforming
    public var driver: Driver?       // NSObject subclass, doesn't conform to Codable

    enum CodingKeys: String, CodingKey {
      case number
      case passenger
    }
  }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我得到一个编译错误

类型'驱动程序'不符合协议'可解码'

到目前为止,我提供的唯一解决方案是通过提供以下方法手动编码和解码:

public init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    number = try? values.decode(String.self, forKey: .number)
    passenger = try? values.decode(Passenger.self, forKey: .passenger) …
Run Code Online (Sandbox Code Playgroud)

json swift swift4 codable decodable

11
推荐指数
1
解决办法
4521
查看次数

可编码类的继承

我正在使用Swift 4和Xcode 9.2编写程序.我在编写可编码类(完全是类,而不是struct)时遇到了困难.当我尝试从另一个类继承一个类时,JSONEncoder不从子类(子)获取所有属性.请看这个:

class BasicData: Encodable {

    let a: String
    let b: String

    init() {
        a = "a"
        b = "b"
    }
}

class AdditionalData: BasicData {

    let c: String

    init(c: String) {
        self.c = c
    }

}

let encode = AdditionalData(c: "c")

do {
    let data = try JSONEncoder().encode(encode)
    let string = String(data: data, encoding: .utf8)
    if let string = string {
        print(string)
    }
} catch {
}
Run Code Online (Sandbox Code Playgroud)

它会打印出来: {"a":"a","b":"b"}

但我需要这个: {"a":"a","b":"b","c":"c"}

它看起来像c类的属性AdditionalData只是失去了某处,不知何故.

所以问题是:如果我有使用协议编码的类Encodable如何正确地创建子类(此类的子类,继承)类?

我会感谢任何帮助或建议.

inheritance swift4 codable decodable encodable

11
推荐指数
1
解决办法
1599
查看次数

`convertFromSnakeCase`策略不适用于Swift中的自定义`CodingKeys`

我尝试使用Swift 4.1的新功能在JSON解码期间将snake-case转换为camelCase.

这是一个例子:

struct StudentInfo: Decodable {
    internal let studentID: String
    internal let name: String
    internal let testScore: String

    private enum CodingKeys: String, CodingKey {
        case studentID = "student_id"
        case name
        case testScore
    }
}

let jsonString = """
{"student_id":"123","name":"Apple Bay Street","test_score":"94608"}
"""

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let decoded = try decoder.decode(StudentInfo.self, from: Data(jsonString.utf8))
    print(decoded)
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

我需要提供自定义,CodingKeys因为convertFromSnakeCase策略无法推断首字母缩略词或首字母缩写词(例如studentID)的大写字母,但我希望convertFromSnakeCase策略仍然适用testScore.但是,解码器抛出错误("没有与键CodingKeys相关的值"),似乎我不能同时使用convertFromSnakeCase策略和自定义 …

ios swift codable jsondecoder

11
推荐指数
1
解决办法
1838
查看次数