微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI 2.0 iOS 14 Core 数据删除实例按下按钮

如何解决SwiftUI 2.0 iOS 14 Core 数据删除实例按下按钮

我想弄清楚如何通过调用我的 viewmodel 中的方法删除核心数据对象的实例。我设法将实例的 id 获取到我的方法可能只是在语法上挣扎。我正在使用 Xcode 12.3 iOS 14.3、SwiftUI 2.0,不再使用 SceneDelegate 或 AppDelegate

这是我的视图模型的样子:

import SwiftUI
import CoreData

class viewmodel : ObservableObject{
@Environment(\.managedobjectContext) private var viewContext
@FetchRequest(entity: Counter.entity(),sortDescriptors: [
        
        NSSortDescriptor(
            keyPath: \Counter.id,ascending: true),NSSortDescriptor(
            keyPath:\Counter.windowType,ascending: true )
    ]) var counters: FetchedResults<Counter>

    //.....




    

以下是我尝试过的并遇到此错误

+entityForName: nil 不是用于搜索实体名称“Counter”的合法 NSPersistentStoreCoordinator

在调试器中逐步执行代码后,这就是我打印 CounterRequested 时得到的

(实体: Counter; predicate: (id == "C4BE9AFF-8A8E-4413-AFA3-AC90850C482E"); sortDescriptors: ((null)); type: NSManagedobjectResultType; )

id 匹配

然后它在 do 块的第一行崩溃

func deleteCounter(id: UUID)  {
    let counterRequested: NSFetchRequest<Counter> = Counter.fetchRequest()
    counterRequested.predicate = nspredicate(format: "id=%@",id.uuidString)
  
    do {
        let savedCounters = try  self.viewContext.fetch(counterRequested)
        
        for counter in savedCounters {
            self.viewContext.delete(counter)
        }
        try self.viewContext.save()
    } catch {
      
        print(error)
    }
 }
}

我从这里获取我的 ID。我可以通过这里的整个柜台吗?不确定要在我的计数器视图中引用什么类型?

List {
       ForEach(counters,id: \.self){counter in
                    
          CounterCell(id: counter.id!,windowType: counter.windowType!,location: counter.location!,pickedImg: counter.pickedImg!,price: counter.price!,qty: counter.qty!,subtotal: counter.subtotal!) .listRowInsets(.init(top: 0,leading: 0,bottom: 20,trailing: 0))

}

这是我想调用删除方法的视图

struct CounterCell: View {
@Environment(\.colorScheme) var colorScheme
@State private var stepperValue = 0
@StateObject var estimatorData = Estimatorviewmodel()

var id: UUID = UUID()
var windowType: String = "Window Type"
var location: String = "Location"
var pickedImg: String = "defaultImg"
var price: String = "0.0"
var qty: String = "0"
var subtotal: String = "0.00"

var body: some View {
   //.....

}

这是我发现的一个例子:

import Foundation
import UIKit
import CoreData

class DataManager {
    
    static let shared = DataManager(moc: NSManagedobjectContext.current)
    
    var managedContext: NSManagedobjectContext
    
    private init(moc: NSManagedobjectContext) {
        self.managedContext = moc
    }
    
    
    // Delete method
    // remove birthday
    func removeBirthday(id: UUID) {
        let fetchRequest: NSFetchRequest<Birthday> = Birthday.fetchRequest()
        fetchRequest.predicate = nspredicate.init(format: "id=%@",id.uuidString)
        do {
            let bdays = try self.managedContext.fetch(fetchRequest)
            for bday in bdays {
                self.managedContext.delete(bday)
            }
            try self.managedContext.save()
        } catch {
          print(error)
        }
    }
    
}

extension NSManagedobjectContext {
    static var current: NSManagedobjectContext {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        return appDelegate.persistentContainer.viewContext
    }
}

解决方法

在您的视图模型中创建一个删除给定对象的方法。

类似的东西

func delete(counter: Counter) {
    do {
        viewContext.delete(counter)
        viewContext.save()
    } catch {
        // handle error
    }
}

我会稍微更新视图代码并让 CounterCell 使用 Counter 属性

struct CounterCell: View {
    @Environment(\.colorScheme) var colorScheme
    @State private var stepperValue = 0
    @StateObject var estimatorData = EstimatorViewModel()

    var counter: Counter

    var body: some View {
   //.....

并相应地更改 ForEach

List {
   ForEach(counters,id: \.self) { counter in
      CounterCell(counter: counter) 
      //...
   }

}

,

经过上述尝试后,我联系了一位高级开发人员,结果证明这是我在视图模型中访问 managedObjectContext 的方式。在此过程中,我了解了如何访问在 Persistence 文件中声明的共享 persistenceController,该文件现在包含在 biolerplate SwiftUI Core Data App 中。

这是我的正确方法。

 var viewContext: NSManagedObjectContext { PersistenceController.shared.container.viewContext }

这是我的删除方法

func deleteCounter(id: UUID)  {
    let counterRequested: NSFetchRequest<Counter> = Counter.fetchRequest()
    counterRequested.predicate = NSPredicate.init(format: "id=%@",id.uuidString)

    do {
        let savedCounters = try  self.viewContext.fetch(counterRequested)
        
        for counter in savedCounters {
            self.viewContext.delete(counter)
        }
        try self.viewContext.save()
    } catch {
        print(error)
    }
}

重构

func deleteWindow(id: UUID)  {
    if let counter = existingCounter {
        viewContext.delete(counter)
        do {
            try viewContext.save()
        } catch {
            print(error)
        }
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。