Проблема с созданием структуры Codable - PullRequest
0 голосов
/ 07 мая 2020

У меня Application протокол с 2 переменными. И у меня есть структура component с переменной, которая подтверждает протокол Application. Мне нужно сохранить это struct на диске. Итак, я подтверждаю это протоколом Codable. При этом я получаю такую ​​ошибку:

«Тип протокола« Приложение »не может соответствовать« Декодируемый », потому что только конкретные типы могут соответствовать протоколам»

Вот мой код,

public protocol Application {
     var name : String {get}
     var ownerName : String {get}
}

public struct component : Codable {
     let application : Application
     private enum CodingKeys: String, CodingKey {
           case application
       }

public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        application = try values.decode(Application.self, forKey: .application)
    }

 public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(application, forKey: .application)
    }
 }

Я новичок в Swift, так что извините, если мне не хватает чего-то очень очевидного. Я не могу это исправить, и мне нужна помощь в правильном направлении. Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 07 мая 2020

То, как вы это решите, сильно зависит от решаемой проблемы.

Если вы хотите сохранить и загрузить именно эти два ключа в JSON, тогда Application должно быть структурой (как отмечает jawadAli).

Если вы хотите сохранить больше информации, но данный Компонент привязан ровно к одному типу Приложения, тогда вы хотите, чтобы Компонент был общим c:

public struct Component<App: Application & Codable> : Codable {
     let application : App
     ...
}

Обратите внимание на добавление & Codable. Если все, что соответствует Application, должно быть кодируемым, вы можете сделать это требованием Application:

public protocol Application: Codable {
     var name : String {get}
     var ownerName : String {get}
}

. Важно понимать, что это не делает приложение совместимым с Codable. Это означает, что для соответствия Application тип также должен соответствовать Codable. Невозможно декодировать абстрактный тип (например, протокол).

Если вы хотите сохранить больше информации, но данный Компонент на самом деле не знает, какое приложение он содержит, тогда это больше сложная проблема (и часто чрезмерно сложная, и ее следует переосмыслить; если вы обнаружите, что используете много as? тестов, вам почти наверняка следует изменить дизайн). Если это ваша проблема, вам следует подробнее объяснить, какую проблему вы решаете, и мы обсудим, как ее решить. (Обычно для этого требуется какая-то система регистрации типов Dynami c и формат JSON, который поддерживает метаданные о типах. Или вы можете переключиться на NSCoder и не использовать JSON.)

2 голосов
/ 07 мая 2020

Использование Struct, подтверждающей возможность кодирования, вместо протокола решит проблему

public struct Application : Codable {
     var name : String
     var ownerName : String
}
...