アプリ内には、文字列とビットマップの2種類のステッカーがあります。各ステッカーパックには、両方のタイプを含めることができます。これは私がモデルを宣言する方法です:
// Mark: - Models
protocol Sticker: Codable {
}
public struct StickerString: Sticker, Codable, Equatable {
let fontName: String
let character: String
}
public struct StickerBitmap: Sticker, Codable, Equatable {
let imageName: String
}
ユーザーがいくつかのステッカーを選択して使用した後、UserDefaults
にステッカーを保存して、「最近使用した」ステッカータブを表示できるようにします。保存した[Sticker]
配列をデコードしようとしています:
let recentStickers = try? JSONDecoder().decode([Sticker].self, from: data)
しかし、次のコンパイルエラーが発生します。
Protocol type 'Sticker' cannot conform to 'Decodable' because only concrete types can conform to protocols
Sticker
もCodable
を実装するDecodable
として宣言したので、なぜか理解できません。どんな助けでも大歓迎です!
ここで何が起こるかは自明です
JSONDecoder().decode(/* Swift here is expecting class or struct that conforms to Codable */.self, from: data)
プロトコルでプロトコルを渡すことができると仮定しましょう
protocol Sticker: Codable {
}
期待しているプロパティはどこですかSwiftデータからデコードする?
プロパティを追加しました
public struct StickerString: Sticker, Codable, Equatable { // it should have redundendant conformance as well as you are conforming to Coddle again
let fontName: String // here is the properties you are expected to be decoded with the coding keys
let character: String // here is the properties you are expected to be decoded with the coding keys
}
デコードしたい型を動的にしたい限り、私はあなたがすることをお勧めします
class GenericService< /* here you can pass your class or struct that conforms to Codable */ GenericResponseModel: Codable> {
func buildObjectFromResponse(data: Data?) -> GenericResponseModel? {
var object : GenericResponseModel?
do {
object = try JSONDecoder().decode(GenericResponseModel.self , from: data!)
} catch (let error){
print(error)
}
return object
}
}
private func handleDecodingTypes (stickers: [Sticker]){
for sticker in stickers {
if sticker is StickerString {
/* do the decoding here */
}
if sticker is StickerBitmap {
/* do the decoding here */
}
}
}