タイプ ''はプロトコル 'デコード可能' / 'エンコード可能'に準拠していません

Dec 23 2020

私はfirestoreから情報を取得するためにこのコードを持っています:

 struct Spty: Identifiable, Codable{
   @DocumentID var id: String? = UUID().uuidString
   var spty: String
   var r: NSNumber
   var g: NSNumber
   var b: NSNumber
}

 class SptyViewModel: NSObject, ObservableObject{
   @Published var specialities = [Spty]()
   @Published var search = ""
     func fetchData(){
      let db = Firestore.firestore()
        db.collection("specialities").addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot else {return }
        self.specialities = documents.documents.compactMap { (doc) -> Spty? in
          let id = doc.documentID
            if  let spty = doc.get("spty") as? String,
            let r = doc.get("r") as?  NSNumber,
            let g = doc.get("g") as?  NSNumber,
            let b = doc.get("b") as?  NSNumber{
            
            return Spty(id: id, spty: spty, r: r , g: g , b: b )
            }
            else{
                return nil
            }
        }
      }
    }

   }

このビデオを見た後、私は自分のコードに変更を加え始めました。しかし、私が追加したように、Codable私はそれらのエラーを受け取りました

タイプ「Spty」はプロトコル「Decodable」に準拠していません

タイプ「Spty」はプロトコル「Encodable」に準拠していません

回答

1 Asperi Dec 23 2020 at 01:49

NSNumberの代わりに、DoubleなどのネイティブSwift型を使用し、他のコードをそれに合わせます

struct Spty: Identifiable, Codable{
   @DocumentID var id: String? = UUID().uuidString
   var spty: String
   var r: Double
   var g: Double
   var b: Double
}
1 SamuelRomero Dec 23 2020 at 22:21

ここでわかるように、「型をコード化可能にする最も簡単な方法は、すでにコード化可能な型を使用してプロパティを宣言することです。これらの型には、String、Int、Doubleなどの標準ライブラリ型と、Date、Data、URLなどのFoundation型が含まれます。 。プロパティがcodableであるタイプは、その適合を宣言するだけで自動的にCodableに適合します。」つまり、codableを使用する場合は、次を使用する必要があります。

  1. 組み込みのコード化可能な型 — String、Int、Double、Data、URL Array、

  2. 辞書、オプションは、コード化可能なタイプが含まれている場合、コード化可能です

NSNumberはCodableタイプの一部ではないため、使用できません。このリンクにはあなたと同様の質問があり、同じ説明を見ることができます。