如何在 Codable 结构中添加自定义瞬态 属性
How to add custom transient property in Codable struct
我有以下可按预期工作的 Codable 结构
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
}
// 标记:Encode/decode 帮助者
class JSONNull: Codable {
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
现在我需要添加不是来自 API 的自定义 属性 来跟踪视频位置所以我修改了它
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
var isPlaying:Bool? // CUSOTM PROPERTY
var currentTime:CMTime? // CUSOTM PROPERTY
var timeObserver:Any? // CUSOTM PROPERTY
var pausedByUser:Bool? // CUSOTM PROPERTY
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
case isPlaying,pausedByUser
case currentTime
case timeObserver
}
}
但是它正在显示
error Type 'VideoAlbum' does not conform to protocol 'Decodable'
有什么办法可以不使用某些 属性 作为 Codable 吗?
我知道问题出在 CMTime 和 Any 我不知道如何解决它
我搜索了很多问题,但所有 属性 都来自 API,没有找到自定义的 属性 有人建议我任何解决方案或替代方法吗?
如果您不想解码这 4 个属性,请不要将它们包含在 CodingKeys
中(并且不要忘记为它们显式提供默认值,以便解码器可以初始化对象正确):
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
var isPlaying: Bool? = nil
var currentTime: CMTime? = nil
var timeObserver: Any? = nil
var pausedByUser: Bool? = nil
enum CodingKeys: String, CodingKey {
// include only those that you want to decode/encode
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
}
首先从结构类型更改为 class。添加不符合 Codable 协议的父级 class,例如 VideoAlbumStatus 并添加这些自定义属性。现在只需从父 class 继承 VideoAlbum。
class VideoAlbumStatus {
var isPlaying:Bool? // CUSOTM PROPERTY
var currentTime:CMTime? // CUSOTM PROPERTY
var timeObserver:Any? // CUSOTM PROPERTY
var pausedByUser:Bool? // CUSOTM PROPERTY
}
class VideoAlbum: VideoAlbumStatus, Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
//TO DO
// init() for VideoAlbum class
}
我有以下可按预期工作的 Codable 结构
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
}
// 标记:Encode/decode 帮助者
class JSONNull: Codable {
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
现在我需要添加不是来自 API 的自定义 属性 来跟踪视频位置所以我修改了它
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
var isPlaying:Bool? // CUSOTM PROPERTY
var currentTime:CMTime? // CUSOTM PROPERTY
var timeObserver:Any? // CUSOTM PROPERTY
var pausedByUser:Bool? // CUSOTM PROPERTY
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
case isPlaying,pausedByUser
case currentTime
case timeObserver
}
}
但是它正在显示
error Type 'VideoAlbum' does not conform to protocol 'Decodable'
有什么办法可以不使用某些 属性 作为 Codable 吗?
我知道问题出在 CMTime 和 Any 我不知道如何解决它
我搜索了很多问题,但所有 属性 都来自 API,没有找到自定义的 属性 有人建议我任何解决方案或替代方法吗?
如果您不想解码这 4 个属性,请不要将它们包含在 CodingKeys
中(并且不要忘记为它们显式提供默认值,以便解码器可以初始化对象正确):
struct VideoAlbum: Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
var isPlaying: Bool? = nil
var currentTime: CMTime? = nil
var timeObserver: Any? = nil
var pausedByUser: Bool? = nil
enum CodingKeys: String, CodingKey {
// include only those that you want to decode/encode
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
}
首先从结构类型更改为 class。添加不符合 Codable 协议的父级 class,例如 VideoAlbumStatus 并添加这些自定义属性。现在只需从父 class 继承 VideoAlbum。
class VideoAlbumStatus {
var isPlaying:Bool? // CUSOTM PROPERTY
var currentTime:CMTime? // CUSOTM PROPERTY
var timeObserver:Any? // CUSOTM PROPERTY
var pausedByUser:Bool? // CUSOTM PROPERTY
}
class VideoAlbum: VideoAlbumStatus, Codable {
let id, image: String?
let video, mediaType: JSONNull?
let type, deleted, createdOn: String?
let modifiedOn: JSONNull?
enum CodingKeys: String, CodingKey {
case id, image, video
case mediaType = "media_type"
case type, deleted
case createdOn = "created_on"
case modifiedOn = "modified_on"
}
//TO DO
// init() for VideoAlbum class
}