You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:18:03