我正在尝试使用UserDefaults
保存配置数据结构,因此该数据结构需要符合Codable
协议。这是我的数据结构:
// Data structure which saves two objects, which conform to the Connection protocol
struct Configuration {
var from: Connection
var to: Connection
}
protocol Connection: Codable {
var path: String { get set }
}
// Two implementations of the Connection protocol
struct SFTPConnection: Connection, Codable {
var path: String
var user: String
var sshKey: String
}
struct FTPConnection: Connection, Codable {
var path: String
var user: String
var password: String
}
如果仅将Codable
添加到Configuration
,它将无法正常工作。所以我必须自己实现。
extension Configuration: Codable {
enum CodingKeys: String, CodingKey {
case from, to
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let from = try container.decode(ConnectionConfiguration.self, forKey: .from)
let to = try container.decode(ConnectionConfiguration.self, forKey: .to)
self.from = from
self.to = to
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(from, forKey: .from)
try container.encode(to, forKey: .to)
}
}
对于decode()
或encode()
的每个呼叫,我都会收到错误Protocol type 'ConnectionConfiguration' cannot conform to 'Decodable/Encodable' because only concrete types can conform to protocols
。
我看到编译器很难识别应该使用哪个类来解码给定的对象。但是我认为对一个对象进行编码应该很容易,因为每个Connection
类型的对象都实现了encode()
方法。
我将不胜感激地解决这个问题!
问题在这里
let from = try container.decode(ConnectionConfiguration.self, forKey: .from)
let to = try container.decode(ConnectionConfiguration.self, forKey: .to)
因为ConnectionConfiguration
是协议而不是具体类型