标签: codable

如何在Swift中表示通用的JSON结构?

我想在Swift中表示一个通用的JSON对象:

let foo: [String: Any] = [
    "foo": 1,
    "bar": "baz",
]
Run Code Online (Sandbox Code Playgroud)

[String: Any]编译器建议的类型并不能很好地工作.我无法检查该类型的两个实例是否相等,例如,虽然这应该可以使用两个JSON树.

什么也行不通的是使用Codable机器将该值编码为JSON字符串:

let encoded = try JSONEncoder().encode(foo)
Run Code Online (Sandbox Code Playgroud)

哪个因错误而爆炸:

fatal error: Dictionary<String, Any> does not conform to Encodable because Any does not conform to Encodable.
Run Code Online (Sandbox Code Playgroud)

我知道我可以引入一个精确的类型,但我遵循通用的JSON结构.我甚至尝试为泛型JSON引入一种特定类型:

enum JSON {
    case string(String)
    case number(Float)
    case object([String:JSON])
    case array([JSON])
    case bool(Bool)
    case null
}
Run Code Online (Sandbox Code Playgroud)

但是当实现Codable这个枚举时我不知道如何实现encode(to:),因为一个键控容器(用于编码对象)需要一个特定的CodingKey参数,我不知道如何得到它.

是否真的不可能创建一个Equatable通用的JSON树并使用它编码Codable

json types swift codable

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

Codable/Decodable 应该用字符串解码数组

为什么名称 Array 没有解码?

为 Playground 做好准备,简单地将其粘贴到您的 Playground 中

import Foundation

struct Country : Decodable {

    enum CodingKeys : String, CodingKey {
        case names
    }

    var names : [String]?
}

extension Country {
    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        names = try values.decode([String]?.self, forKey: .names)!
    }
}

let json = """
 [{
    "names":
      [
       "Andorre",
       "Andorra",
       "????"
      ]
 },{
    "names":
      [
       "United Arab Emirates",
       "Vereinigte Arabische Emirate",
       "Émirats Arabes Unis",
       "Emiratos Árabes Unidos",
       "????????",
       "Verenigde …
Run Code Online (Sandbox Code Playgroud)

swift swift4 codable decodable

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

如何将 CodingKeys 用于符合 Codable 协议的枚举?

我有一个符合协议EmailVerificationStatus的关联类型的枚举:StringCodable

enum EmailVerificationStatus: String, Codable {
    case unverified
    case verified
}
Run Code Online (Sandbox Code Playgroud)

我正在使用的网络服务以大写 ( UNVERIFIED/ VERIFIED)发送这些案例。我如何使用CodingKeys枚举来映射这种差异?类似以下内容不起作用:

enum CodingKeys: String, CodingKey {
    case unverified = "UNVERIFIED"
    case verified = "VERIFIED"
}
Run Code Online (Sandbox Code Playgroud)

enums ios swift4 codable

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

获取 KeyPath 的特定 CodingKey

考虑以下对象:

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

是否有可能获得CodingKey给定的特定信息KeyPath

let key = \User.name.codingKey  // would be equal to string: "name"
Run Code Online (Sandbox Code Playgroud)

key-value-coding ios swift swift4 codable

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

Swift 4可编码和通用

我正在使用PINCache将缓存添加到我的应用中,并且处于缓存系统调用编码/解码的委托方法的情况。这些方法是通用的,但通用值未明确符合Codable。因为它们是委托,所以我无法更改签名以使泛型类型符合Codable

func modelForKey<T : SimpleModel>(_ cacheKey: String?, context: Any?, completion: @escaping (T?, NSError?) -> ()) {
    guard let cacheKey = cacheKey, let data = cache.object(forKey: cacheKey) as? Data, T.self is Codable else {
        completion(nil, nil)
        return
    }

    let decoder = JSONDecoder()
    do {
        let model: T = try decoder.decode(T.self, from: data)
        completion(model, nil)
    } catch {
        completion(nil, nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,我遇到以下错误:

在参数类型中T.TypeT与预期类型不符Decodable

如何强迫我decoder接受通用价值?

generics swift swift4 codable

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

如何处理Swift中一个键的两种可能类型的解码?

我有一个Codable结构,用于解码传入的JSON.不幸的是,有时它的一个键的值是一个字符串,有时它是一个浮点数.我能够在下面拼凑一些do/try/catch块以使其工作,但是有更好的方法来处理它吗?

struct Project: Codable {
    public let version: Float

    init(from decoder: Decoder) throws {
        var decodedVersion: Float = 1.0
        do {
            decodedVersion = try values.decode(Float.self, forKey: .version)
        } catch {
            do {
                if let inVersion = try Float(values.decode(String.self, forKey: .version)) {
                    decodedVersion = inVersion
                }
            } catch {
                throw error
            }
        }
        version = decodedVersion
    }
}
Run Code Online (Sandbox Code Playgroud)

swift codable

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

CoreLocation 类的可编码扩展

我需要添加Codable两个类。一是CLLocationCoordinate2D,二是CLCircularRegion

我对此没有任何问题CLLocationCoordinate2D,并且可以通过这样做来实现:

extension CLLocationCoordinate2D: Codable {
    public enum CodingKeys: String, CodingKey {
        case latitude
        case longitude
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(latitude, forKey: .latitude)
        try container.encode(longitude, forKey: .longitude)
        }

    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        latitude = try values.decode(Double.self, forKey: .latitude)
        longitude = try values.decode(Double.self, forKey: .longitude)
    }
}
Run Code Online (Sandbox Code Playgroud)

但我在尝试做同样的事情时遇到了很多问题CLCircularRegion。由于radiuscenter是只读属性,我无法真正以相同的方式创建它们。另一个问题是为什么我能够创建public …

core-location ios swift codable

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

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
查看次数

类型“ X”不符合协议“可编码”

我希望在这里能理解此错误,并且可能对可编码和可解码的内容有更广泛的了解。我班的一部分看起来如下:

  public var eventId: String?
  public var eventName: String?
  public var eventDescription: String?
  public var location: CLLocation?

  /// These properties will be encoded/decoded from JSON
  private enum CodingKeys: String, CodingKey {
    case eventId
    case eventName
    case eventDescription
    case location
  }

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

    let eventId = try container.decode(String?.self, forKey: .eventId)
    let eventName = try container.decode(String?.self, forKey: .eventName)
    let location = try container.decode(CLLocation?.self, forKey: .location)
    self.init(eventId: eventId, eventName: eventName, location:location) …
Run Code Online (Sandbox Code Playgroud)

xcode ios swift codable

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

使用Codable(Swift)从Json文件解析UIColor

我试图解码一个json文件,并且我在那里有很多ui配置,我正在寻找一个干净的解决方案以直接将十六进制代码解析为UIColor。但是UIColor不符合Codable。

例如这个json:

var json = """
{
    "color": "#ffb80c"
}
""".data(using: .utf8)!
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这一点:

struct Settings: Decodable {
    var color: UIColor
}
Run Code Online (Sandbox Code Playgroud)

并且即时解码时将“ hex”字符串转换为UIColor

我已经有了此函数来从String解码并返回UIColor:

public extension KeyedDecodingContainer {

    public func decode(_ type: UIColor.Type, forKey key: Key) throws -> UIColor {

        let colorHexString = try self.decode(String.self, forKey: key)
        let color = UIColor(hexString: colorHexString)

        return color
    }
}
Run Code Online (Sandbox Code Playgroud)

为此,我需要通过获取容器并对其进行解码来对其进行手动解码,但是由于我有很多配置,因此我的课程非常庞大,因为我需要设置所有内容:

struct Settings: Decodable {

    var color: Color

    enum CodingKeys: CodingKey {

        case color
    }

   init(from decoder: Decoder) throws {

        let container = try …
Run Code Online (Sandbox Code Playgroud)

iphone json ios swift codable

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