簡體   English   中英

類不符合 Encodable

[英]Class does not conform to Encodable

但是,收到一條錯誤消息,指出我的類“費用”不符合協議“可解碼”和“費用”類型不符合協議“可編碼”

import Foundation

class Expenses : ObservableObject, Codable  {
    
    @Published var items : [ExpenseItem] {
        // Step 1 creat did set on publsihed var.
        didSet {
            let encoder = JSONEncoder()
            if let encoded = try? encoder.encode(items) {
                UserDefaults.standard.set(encoded, forKey: "Items")
            }
        }
    }

    init() {
        if let items = UserDefaults.standard.data(forKey: "Items") {
            let decoder = JSONDecoder(
            if let decoded = try?
                decoder.decode([ExpenseItem].self, from: items) {
                self.items = decoded
                return
            }
        }
        self.items = []
    }     
}

我的費用項目被標記為

struct ExpenseItem : Identifiable, Codable   {
    let id = UUID()
    let name : String
    let type : String
    let amount : Int       
}

一致性Encodable / Decodable是自動合成時所有存儲的性能符合Encodable / Decodable ,但使用上的屬性的裝置,現在的屬性包裝類型的需求,以符合一屬性包裝Encodable / Decodable

@Published屬性包裝器不符合。 只在Published類型本身上實現一致性會很好,但不幸的是它沒有公開包裝的值,所以不使用反射(我在網上看到了建議),我認為這是不可能的。

您需要手動實現一致性:

class Expenses : ObservableObject {
   @Published var items : [ExpenseItem]

   // ... rest of your code
}

extension Expense: Codable {
   enum CodingKeys: CodingKey {
      case items
   }
    
   func encode(to encoder: Encoder) throws {
      var container = encoder.container(keyedBy: CodingKeys.self)
      try container.encode(self.items, forKey: .items)
   }

   required init(from decoder: Decoder) throws {
      var container = try decoder.container(keyedBy: CodingKeys.self)
      self.items = try container.decode([ExpenseItem].self, forKey: .items)
   }      
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM