Typ „” nie jest zgodny z protokołem „Decodable” / „Encodable”

Dec 23 2020

Mam ten kod, aby uzyskać informacje z 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
            }
        }
      }
    }

   }

po obejrzeniu tego filmu zacząłem wprowadzać zmiany w moim kodzie. Ale jak dodałem Codable, otrzymałem te błędy

Typ „Spty” nie jest zgodny z protokołem „Decodable”

Typ „Spty” nie jest zgodny z protokołem „Encodable”

Odpowiedzi

1 Asperi Dec 23 2020 at 01:49

Zamiast NSNumber użyj natywnych typów Swift, takich jak Double, i dopasuj inny kod do tego

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

Jak widać tutaj „Najprostszym sposobem uczynienia typu możliwym do zakodowania jest zadeklarowanie jego właściwości przy użyciu typów, które są już kodowalne. Te typy obejmują standardowe typy bibliotek, takie jak String, Int i Double; oraz typy Foundation, takie jak Date, Data i URL . Każdy typ, którego właściwości są kodowalne, automatycznie dostosowuje się do Codable tylko przez zadeklarowanie tej zgodności. " Oznacza to, że jeśli chcesz używać kodowania, musisz użyć:

  1. Wbudowane typy kodowalne  - String, Int, Double, Data, URL Array,

  2. Słownik, opcjonalne są kodowane, jeśli zawierają typy kodowane

Ponieważ NSNumber nie jest częścią typów Codable, nie możesz go używać. Ten link ma podobne pytanie do twojego i możesz tam zobaczyć to samo wyjaśnienie.