最小化应用程序后,SwiftData udpate 布尔值未保存

问题描述 投票:0回答:1

我在更新 SwiftData 模型上的 Bool 时遇到问题,一开始它正在改变。但是,如果我最小化/关闭应用程序并再次重新打开,则会添加返回到第一次记录的值(错误)

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"
    }
}
}

这是模型

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
}
}

让我困惑的是,为什么当我更改字符串时,即使我最小化或关闭应用程序,它仍然持久并保存,但不是 isDelete?已经5个小时了我试图找到我做错的地方但仍然没有找到它T_T...

swift swiftui swiftdata
1个回答
0
投票

您遇到的问题似乎是因为对 isDeleted 的更改没有保存到您的持久存储中。在 SwiftData 中,为了确保即使在应用程序关闭后更改仍然存在,您需要在修改模型后显式保存上下文。

在您的deleteReactivateCategory函数中,更新isDeleted属性后,添加一个调用来保存上下文:

private func deleteReactivateCategory(_ categoryRecord: Category, isDelete: Bool) {
    if let index = categories.firstIndex(where: { $0.id == categoryRecord.id }) {
        categories[index].isDeleted = isDelete
        do {
            try context.save()
        } catch {
            print("Failed to save context: \(error)")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.