我尝试过这里和其他地方提出的各种解决方案(例如,向Collection添加扩展、[safe]元素迭代等(,但不幸的是,没有任何效果。我也尝试过改变";最后"至";首先"在onDelete代码中,但这会导致同样的问题,尽管令人惊讶的是,它确实适用于我看到的其他线程中的其他线程。我应该注意的是,只有当我在应用程序中结合了CoreData和Firebase时,这种情况才开始发生。。。非常感谢您的帮助。提前谢谢。
类,用作环境对象并启动Firebase:
class DayData: ObservableObject, Identifiable {
@Published var date = Date()
@Published var completed = false
@Published var percentage: Double = 0.0
@Published var liquids: Double = 0
var allData : [DayCellModel] = []
let dbRef = Firestore.firestore()
init() {
readAllData()
}
func readAllData(){
dbRef.collection("keanu").addSnapshotListener{ (snap, err) in
guard let docs = snap else { return }
self.allData = docs.documents.compactMap({ (doc) -> DayCellModel? in
return try! doc.data(as: DayCellModel.self)
})
}
DayCellModel结构仅用于Firebase:
struct DayCellModel : Identifiable, Codable {
@DocumentID var id: String?
var date : Date = Date()
var completed : Bool = false
var percentage : Double = 0.0
var liquids: Int = 0
}
仅用于CoreData:的数据模型类
extension NSDayData {
@nonobjc public class func getDayData() -> NSFetchRequest<NSDayData> {
let request:NSFetchRequest<NSDayData> = NSDayData.fetchRequest() as! NSFetchRequest<NSDayData>
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
@NSManaged public var completed: Bool
@NSManaged public var id: UUID?
@NSManaged public var liquids: Double
@NSManaged public var percentage: Double
@NSManaged public var date: Date?
}
extension NSDayData : Identifiable {
}
结构包含代码到我的列表和onDelete代码:
struct ListView: View {
@Environment(.managedObjectContext) var moc
@FetchRequest(fetchRequest : NSDayData.getDayData()) var dayItems:FetchedResults<NSDayData>
@EnvironmentObject var data : DayData
var body: some View {
NavigationView{
VStack(spacing: 10){
HStack{
Text("Date")
Text("Completion")
Text("Liquids")
}.font(.caption)
List{
ForEach(dayItems, id: .id) { collection in
HStack{
Text("(collection.date?.string(format: self.dateFormat) ?? Date().string(format: self.dateFormat))")
Text(collection.percentage > 0.95 ? "100%" : "(Int(collection.percentage * 100))")
Text("(Int(collection.liquids))oz")
}.font(.system(size: 10, weight: .light))
}.onDelete{ (index) in
let db = Firestore.firestore()
db.collection("keanu")
.document(self.data.allData[index.last!].id!)
.delete { (err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
}
self.deleteItems(at: index)
}
}
}
func deleteItems(at offsets: IndexSet) {
withAnimation{
offsets.map { dayItems[$0] }.forEach(moc.delete)
saveMoc()
data.allData.remove(atOffsets: offsets)
}
}
我有另一个视图,我可以添加新的数据并将其保存到Firebase和CoreData中,如下所示:
if self.newCollection {
let dayData = NSDayData(context: self.moc)
dayData.id = UUID()
dayData.date = self.data.date
dayData.completed = self.data.percentage > 0.95
dayData.percentage = self.data.percentage
dayData.liquids = self.data.liquids
do {
try moc.save()
} catch {
let error = error as NSError
fatalError("Unresolved Error: (error)")
}
let db = Firestore.firestore()
db.collection("keanu").document()
.setData(
[
"date": self.data.date,
"completed": self.data.percentage > 0.95,
"percentage": self.data.percentage,
"liquids": self.data.liquids
]) { (err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
}
好吧,所以我在youtube上看了kavsoft的一些很棒的视频后终于明白了。对于那些可能遇到类似问题的人,以下是我的解决方案:
-
不要在ForEach上使用onDelete{}函数。相反,创建一个按钮来删除项目,这样您就不必处理索引了。
-
如果使用CoreData&Firebase,创建一个与结构和核心数据类等效的字符串变量(见下文(。
-
在编辑视图(添加新视图等(中,我创建了以下内容:
@绑定var docID:String
-
在列表视图中,为docID 的绑定变量创建一个@State
@状态var docID=">
然后,当我从列表中显示编辑视图时,它显示如下:
.sheet(isPresented: $show, content: {
EditView(docID: $docID, show: self.$show newEntry: true)
.environment(.managedObjectContext, self.moc)
})
我添加了一个按钮,可以同时从Firebase、CoreData和列表中删除条目。这是嵌套在ForEach中的,所以您可以得到一个";减去";列表中每个项目旁边的符号:
if self.remove{ VStack{ Button(action: { let db = Firestore.firestore() db.collection("myCollection").document(docID).delete() moc.delete(collection) saveMoc() } }) { Image(systemName: "minus.circle.fill") }.buttonStyle(BorderlessButtonStyle()) }
5.2。我还有一个导航栏按钮,它触发"-"出现的符号
var deleteButton : some View {
Button(action: {
self.remove.toggle()
}) {
Image(systemName: self.remove ? "xmark.circle" :
"trash")
}
最后,在保存我设置的条目时CoreData属性:
let dayData = NSDayData(context: self.moc) dayData.id = self.docID
Firebase属性:
let db = Firestore.firestore()
db.collection("yourCollection").document(self.docID)
.setData(
[
"id": self.docID,
...