我有这个协议,

protocol PaginableItem {
   var resultType: ResultType { get set }
}

对于枚举类型的单个属性,
enum ResultType: String, Codable {
   case photo = "PHOTO"
   case baseItem = "BASEITEM"
   case new = "NEW"
}

我还有3个不同的结构和类,它们都符合PaginableItem,还有一个类有一些PaginableItems
final class TimelineModel: Codable {
   let stream: String
   let participants: String
   let header1: PaginableList
   let header2: PaginableList
   let items: PaginableList
}

final class PaginableList: Codable {
   let data: [PaginableItem]
   let pagination: Pagination
}

我正在尝试使用swift 4缓存TimelineModel,但我不确定最好的方法。xcode抱怨Codable不符合PaginableItem
必须在Codable中执行init(from decoder: Decoder) throwsencode(to encoder: Encoder) throws
必须同时执行?

最佳答案

PaginableItem不能符合Codable是因为swift协议不能符合自身。
资料来源:
Protocol doesn't conform to itself?
Encode/Decode Array of Types conforming to protocol with JSONEncoder
在上面的第二个链接之后,如果要对aPaginableItem进行编码/解码,必须在一个AnyPaginableItem类/结构中键入erase,并使其符合Encodable/Decodable。我是这样做的:

protocol PaginableItem {
    var resultType: ResultType { get set }
}

class AnyPaginableItem: Codable {
    var resultType: ResultType

    init(resultType: ResultType) {
        self.resultType = resultType
    }
}

enum ResultType: String, Codable {
    case photo = "PHOTO"
    case baseItem = "BASEITEM"
    case new = "NEW"
}

struct ContainsPaginableItem: Codable {
    let paginableItem: AnyPaginableItem
}

let paginableItem = AnyPaginableItem(resultType: .photo)
let itemToEncode = ContainsPaginableItem(paginableItem: paginableItem)

let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(itemToEncode)
let jsonString = String(data: jsonData, encoding: .utf8)

这个例子只编码可以在PaginableItem中声明的属性,我认为这是您所需要的全部。
如果您需要对符合PaginableItem的类型的所有属性进行编码,那么在上面的第二个链接中可以采用一个更长的解决方案。

关于swift - 带有枚举属性的Swift 4 Codable协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47579687/

10-11 23:00