致命错误:在SwiftUI中从列表内的Firebase中删除项目时,索引超出范围



我尝试过这里和其他地方提出的各种解决方案(例如,向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的一些很棒的视频后终于明白了。对于那些可能遇到类似问题的人,以下是我的解决方案:

  1. 不要在ForEach上使用onDelete{}函数。相反,创建一个按钮来删除项目,这样您就不必处理索引了。

  2. 如果使用CoreData&Firebase,创建一个与结构和核心数据类等效的字符串变量(见下文(。

  3. 在编辑视图(添加新视图等(中,我创建了以下内容:

@绑定var docID:String

  1. 在列表视图中,为docID 的绑定变量创建一个@State

    @状态var docID=">

然后,当我从列表中显示编辑视图时,它显示如下:

.sheet(isPresented: $show, content: {
EditView(docID: $docID, show: self.$show newEntry: true)

.environment(.managedObjectContext, self.moc)
})
  1. 我添加了一个按钮,可以同时从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")

}

  1. 最后,在保存我设置的条目时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,
...

相关内容

  • 没有找到相关文章

最新更新