如何解码/编码不同泛型类型的数组?
我有一个数据结构,它具有符合协议的属性Connection
,因此我使用泛型:
// Data structure which saves two objects, which conform to the Connection protocol
struct Configuration<F: Connection, T: Connection>: Codable {
var from: F
var to: T
private var id: String = UUID.init().uuidString
enum CodingKeys: String, CodingKey {
case from, to, id
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.from = try container.decode(F.self, forKey: .from)
self.to = try container.decode(T.self, forKey: .to)
self.id = try container.decode(String.self, forKey: .id)
}
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)
try container.encode(id, forKey: .id)
}
}
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
}
当我知道连接类型时,这很好用F
and T
是。但我有一些情况,我想加载配置,但不知道哪种类型F
and T
are.
public static func load<F: Connection, T: Connection>(for key: String) throws -> Configuration<F, T>? {
// Load from UserDefaults
guard let configurationData = defaults.object(forKey: key) as? Data else {
return nil
}
// Decode
guard let configuration = try? PropertyListDecoder().decode(Configuration<F, T>.self, from: configurationData) else {
return nil
}
return configuration
}
// OR
func loadAll<F:Connection, T: Connection>() -> [String: Configuration<F, T>]? {
return UserDefaults.standard.dictionaryRepresentation() as? [String: Configuration<F, T>]
}
在上述情况下F
and T
可以是任何未知类型,符合Connection
协议。所以上面的函数不起作用,因为我需要指定一个特定的类型F
and T
当调用该函数时,我不知道。
在第二个函数中,F
实际上可能有不同的类型。这就是困难所在。我想我需要以某种方式存储类型F
and T
也在用户默认值中,然后在decode
and encode
函数(从而丢弃泛型)。但我不知道如何优雅地做到这一点。
我将不胜感激任何关于如何解决这个问题的想法!