SwiftData模型中Bool类型属性更新后无法持久化,但String属性正常的问题求助
SwiftData模型中Bool类型属性更新后无法持久化,但String属性正常的问题求助
我现在遇到一个SwiftData的棘手问题:当我更新模型里的Bool类型属性isDeleted时,当时界面上能看到变化,但只要把App最小化或者完全关闭再重新打开,这个属性值就会变回该记录刚创建时的初始值false。
但特别奇怪的是,同样是修改这个模型里的String类型属性name,修改后就能正常持久化,重启App后修改的内容也不会丢失。
以下是我的代码:
CategoryList 视图代码
import SwiftUI import SwiftData struct CategoryList: View { @Environment(\.modelContext) private var context @Query var categories: [Category] @State private var isFormSheetPresented = false // State for presenting the Add Category form var body: some View { List { // Active Categories Section(header: Text("Active Categories") .font(.headline) .foregroundColor(.black)) { // Header with black text ForEach(activeCategories) { category in HStack { Text(category.name) .foregroundColor(.darkSpringGreen) Spacer() if !category.isDefault { // Show a delete button for non-default categories Image(systemName: "trash") .foregroundColor(.red) .onTapGesture(perform: { deleteReactivateCategory(category, isDelete: true) }) } } } } .listRowBackground(Color.white) // Set white background for the section // Deleted Categories Section(header: Text("Deleted Categories") .font(.headline) .foregroundColor(.black)) { // Header with black text ForEach(deletedCategories) { category in HStack { Text(category.name) .foregroundColor(.lightSilver) // Indicate that it's deleted Spacer() Image(systemName: "arrow.trianglehead.counterclockwise.rotate.90") .foregroundColor(.red) .onTapGesture(perform: { deleteReactivateCategory(category, isDelete: false) }) } } } .listRowBackground(Color.white) // Set white background for the section } .listStyle(PlainListStyle()) // Use plain list style to remove default styling .navigationTitle("Categories") // Title is centered by default .navigationBarTitleDisplayMode(.inline) // Make title not large .navigationBarItems(trailing: Button(action: { isFormSheetPresented = true // Present the form }) { Text("Add") }) .sheet(isPresented: $isFormSheetPresented) { CategoryForm(isEdit: false, dismissAction: { isFormSheetPresented = false // Dismiss action for the form }, addAction: { newCategoryName in let newCategory = Category(name: newCategoryName, isDefault: false, isDeleted: false) let swifDataService = SwiftDataService(context: context) do { try swifDataService.createCategory(newCategory: newCategory) isFormSheetPresented = false } catch { print("-- Cateogy failed to add \(newCategoryName)") } }).presentationDetents([.medium]) } } // Computed properties to separate active and deleted categories private var activeCategories: [Category] { categories .filter { !$0.isDeleted } // Filter out deleted categories .sorted { (first, second) -> Bool in // Check if either category is named "Others" if first.name == "Others" { return false // "Others" should come last } if second.name == "Others" { return true // "Others" should come last } // Otherwise, sort alphabetically return first.name < second.name } } private var deletedCategories: [Category] { categories.filter { $0.isDeleted } } private func deleteReactivateCategory(_ categoryRecord: Category, isDelete: Bool) { let updateCategories = categories if let index = updateCategories.firstIndex(where: { $0.id == categoryRecord.id }) { updateCategories[index].isDeleted = true updateCategories[index].name = "Test Changing the name" } } }
Category 模型代码
import Foundation import FirebaseFirestore import SwiftData @Model class Category: Codable, Identifiable { @Attribute(.unique) var id: String var name: String var isDefault: Bool var isDeleted: Bool // Custom CodingKeys to map property names for encoding/decoding enum CodingKeys: String, CodingKey { case id, name, isDefault, isDeleted } // Required initializer to decode data required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(String.self, forKey: .id) name = try container.decode(String.self, forKey: .name) isDefault = try container.decode(Bool.self, forKey: .isDefault) isDeleted = try container.decode(Bool.self, forKey: .isDeleted) } // Encode function to encode data func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(name, forKey: .name) try container.encode(isDefault, forKey: .isDefault) try container.encode(isDeleted, forKey: .isDeleted) } // Initializer for creating new instances of Category init(id: UUID = UUID(), name: String, isDefault: Bool, isDeleted: Bool) { self.id = id.uuidString self.name = name self.isDefault = isDefault self.isDeleted = isDeleted } }
我真的搞不明白问题出在哪——同样是修改模型属性,String类型的name就能正常持久化,可Bool类型的isDeleted修改后重启App就复原,有没有大佬能帮我分析一下原因呀?
备注:内容来源于stack exchange,提问作者Garpepi
相关产品推荐
相关产品推荐

