使用协议类型属性解码/编码结构

问题描述 投票:0回答:1

我正在尝试使用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()方法。

我将不胜感激地解决这个问题!

swift encoding protocols decode codable
1个回答
0
投票

问题在这里

let from = try container.decode(ConnectionConfiguration.self, forKey: .from)
let to = try container.decode(ConnectionConfiguration.self, forKey: .to)

因为ConnectionConfiguration是协议而不是具体类型

© www.soinside.com 2019 - 2024. All rights reserved.