忽略 Codable 对象中的非 Codable 可选属性
Posted
技术标签:
【中文标题】忽略 Codable 对象中的非 Codable 可选属性【英文标题】:Ignore non-Codable optional properties in Codable object 【发布时间】:2018-03-30 13:43:24 【问题描述】:当符合Codable
协议时,我不能轻易跳过非Codable类的可选属性
在Ride
struct 中,我们要跳过driver
属性的encoding 和decoding,在解码时只保留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
在这种情况下,我得到一个编译错误
类型“驱动程序”不符合协议“可解码”
到目前为止,我提供的唯一解决方案是通过提供以下方法手动编码和解码:
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)
public func encode(to encoder: Encoder) throws
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(passenger, forKey: .passenger)
还有其他方法可以跳过可选属性吗?使用更大的模型会更容易。
【问题讨论】:
这是一个错误,请看这条评论链:***.com/questions/46104870/… 【参考方案1】:尝试为driver
提供一个默认值。例如,这在 Xcode 9.0 上编译没有错误:
struct Ride: Codable
public var number: String
public var passenger: Passenger?
public var driver: Driver? = nil
private enum CodingKeys: String, CodingKey
case number
case passenger
struct Passenger: Codable /* ... */
class Driver: NSObject /* ... */
快速测试:
let rideJSON =
"""
"number": "123"
""".data(using: .utf8)!
let ride = try! JSONDecoder().decode(Ride.self, from: rideJSON)
print(ride) /* Ride(number: "123", passenger: nil, driver: nil) */
顺便说一句,我使用了private CodingKeys
,因为这也是编译器默认执行的操作;)
【讨论】:
打印的编译器错误对这个问题非常有帮助:note: cannot automatically synthesize 'Decodable' because 'driver' does not have a matching CodingKey and does not have a default value
@mklbtz 好收获!可能是 Xcode 9.2 的改进...或者我们第一次完全错过了这个(有用的!)消息;)很多人甚至懒得阅读/解释这样的消息...以上是关于忽略 Codable 对象中的非 Codable 可选属性的主要内容,如果未能解决你的问题,请参考以下文章