Generic Decodable停止使用swift 4.1

时间:2018-04-29 17:38:49

标签: swift generics codable decodable jsondecoder

因此,我们在API中有两种类型的JSON响应:

{
  "data": { } // some object in here
  "meta": { } // an object in here
}

{
  "data": [ ] // array of objects
  "meta": { } // an object in here
}

要解码它们,我们使用JSONDecoder()和以下通用响应结构:

public struct Response<T: Codable>: Codable {
    public let data: T
    public let meta: Meta?
}

这适用于使用.map(Response<[MyObject]>.self).map(Response<MySingleObject>.self)

的Swift 4.0

但由于某种原因,这不再适用于Swift 4.1和Xcode 9.3。看起来它没有映射&#34;数据&#34;根本就认为[MyObject]的列表在第一级。

dataCorrupted: Swift.DecodingError.Context
      ▿ codingPath: 3 elements
        - CodingKeys(stringValue: "data", intValue: nil)
        ▿ _JSONKey(stringValue: "Index 0", intValue: 0)
          - stringValue: "Index 0"
          ▿ intValue: Optional(0)
            - some: 0
        - CodingKeys(stringValue: "creationDate", intValue: nil)
      - debugDescription: "Date string does not match format expected by formatter."

请注意&#34; creationDate&#34;是MyObject的属性。日期格式绝对正确(在解码器中设置为.formatted(customFormatter),因为它与Xcode 9.2中的Swift 4.0一起使用

我们如何才能在Swift 4.1中使用相同的行为?这里的目标是不为每个API响应创建一个类型化的Response类型,而是使用泛型,因为唯一的区别是响应对象类型,有时它会返回一个列表,有时会返回{{1}下面的单个对象}。

同样相关:如果我们使用data同时Response<[MyObject]>.self必须符合MyObject,还有办法强制执行吗?

提前致谢。

编辑:

下面的代码在Xcode 9.2和Swift 4中正确映射,但在Xcode 9.3和Swift 4.1中没有映射(创建nil)

Codable

1 个答案:

答案 0 :(得分:0)

我没有收到任何错误。请发布。作为练习,我添加了CustomStringConvertible一致性,并将dump替换为print。

extension Response: CustomStringConvertible {
  public var description: String {
    return "data = \(data) | meta = \(meta)"
  }
}

extension MyObject: CustomStringConvertible {
  public var description: String {
    return "date = \(creationDate)"
  }
}

我正在使用通过App Store发布的Xcode 9.3,Swift 4.1版本9E145。

enter image description here