「タイプ「ブックマーク」がプロトコル「デコード可能」に適合していません」というエラーメッセージが表示されるのはなぜですか?
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
}
出版物はブックマークを所有しているが、ブックマークはそれが属する出版物を知る必要があるため、出版物変数を保存したくない。 Publicationのデコード初期化は、ブックマーク参照をそれ自体に設定します。
「タイプ「ブックマーク」がプロトコル「デコード可能」に準拠していません」というエラーメッセージが表示されるのはなぜですか
PublicationがDecodableではないため(それが何であるかを示していないため、わかりにくい)、またはweak
でpublication
が指定されているためです。
どちらにしても、簡単に修正できます。Decodeableの実装を完了するには、init(from:)
を実装するだけです。コンパイラは、この実装を合成できないことを単に伝えています。
コンパイラは、weak
参照のために必要なinit(from:)
メソッドを合成できないため、自分で作成する必要があります。
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
private enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
required init(from decoder:Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
indexPath = try values.decode([Int].self, forKey: .indexPath)
locationInText = try values.decode(Int.self, forKey: .locationInText)
}
}
このメッセージが表示されるもう1つの理由は、CodingKeys列挙型が網羅的でない場合です。データ型に3つのプロパティがある場合、CodingKeys列挙には3つのプロパティ/名前のケースも必要です。
CodingKeys列挙型が完全ではないという理由だけで、publication
プロパティを列挙型に追加してそれを実現します。
これを試して:
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
// All your properties should be included
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
case publication // this one was missing
}
}
実装を合成できるようになったため、initメソッドはもう必要ありません。
要するに、Codableの実装中、非プリミティブデータ型(平均クラス型またはObjective-Cクラスの可能性がある)であるすべてのプロパティはCodableでなければなりません。
weak var publication: Publication?
この場合、パブリケーションはタイプクラスであるため、パブリケーションはCodableを実装する必要があります。
デフォルト値がある場合にのみ、コーディングキー列挙からプロパティを省略できます。
Apple docs から
インスタンスをデコードするときにプロパティが存在しない場合、または特定のプロパティをエンコードされた表現に含めない場合は、CodingKeys列挙からプロパティを省略します。 CodingKeysから省略されたプロパティは、その包含型がDecodableまたはCodableへの自動適合を受け取るためにデフォルト値を必要とします。
私はこの修正につまずいた同様の問題を抱えていました。私はSwiftを初めて使用するので、なぜそれが機能するのか分かりません!誰もが知っているなら、私は知識を感謝します。
これを変更しました:
let id, type: Int
これに:
let id: Int
let type: Int