[英]How to handle data deletions in SwiftUI (iOS) without crashing the app
我有一个 SwiftUI 日历应用程序,其 UI 类似于内置的 Calendar.app。 每当我尝试删除事件时,我都会崩溃。 我的应用程序的整体生命周期如下:
当我这样做时,我会因计算值而崩溃,因为详细视图中显示的事件数据不再可用。 比如我得到一个用户的RSVP的数组索引如下:
var responseIndex: Int {
userData.responses.firstIndex(where: { $0.user == response.user && $0.occurrence == response.occurrence })!
}
我以为这是因为我在更新数据之前没有关闭显示已删除事件的视图,但即使我延迟数据刷新直到视图不再显示,我仍然会崩溃(SwiftUI 似乎将这些视图保留在记忆)。
处理数据删除的正确方法是什么? 我是否需要在我的 UserData EnvironmentObject 中保留已删除的事件并将它们标记为“已删除/隐藏”以避免此问题,或者是否有更好的方法来处理它?
这涉及到相当多的代码,所以提供一个示例很棘手,如果有人问我很乐意添加相关位。
编辑:我发现这篇文章很好地阐明了一些事情: https ://jasonzurita.com/swiftui-if-statement/
SwiftUI 非常乐意尝试渲染 nil 视图,它什么也不画。 与直觉相反,避免崩溃并使编译器满意的一个好方法是围绕此设置代码。
原始“答案”如下...
我不知道这是否是执行此操作的“正确”方法,但我最终确保我的 UserData 都没有被删除以避免崩溃。 我向我的 Occurrence(即事件)对象添加了一个“已删除”布尔值,当我刷新我的结构化数据时,我从服务器获取最新数据,但检查是否有任何旧数据不再存在。 步骤是:
代码如下所示:
init(occurrences: [Occurrence], existing: [Day]) {
// Create a mutable copy of occurrences (useful so I can delete duplicates)
var occurrences = occurrences
// Flatten the structured data into a plan array of occurrences again
var existingOccurrences = existing.compactMap({ $0.occurrences }).flatMap { $0 }
// Go through existing occurrences and see if they still exist.
existingOccurrences = existingOccurrences.map {
occurrence -> Occurrence in
let occurrenceIndex: Int? = occurrences.firstIndex(where: { $0.id == occurrence.id })
// If the occurrence no longer exists, mark it as "deleted" in the original data
if occurrenceIndex == nil {
var newOccurrence = occurrence
newOccurrence.deleted = true
return newOccurrence
// If it still exists, replace the existing copy with the new copy
// (in case it has changed since the last pull from the server)
// Remove the event from the "new" data so you don't get duplicates
} else {
let newOccurrence = occurrences[occurrenceIndex!]
occurrences.remove(at: occurrenceIndex!)
return newOccurrence
}
}
// Merge the existing data (with deleted items marked) and the updated data (with deleted items removed)
let finalOccurrences = existingOccurrences + occurrences
// Re-initialize the strutured data with the new array of data
self = EventData(occurrences: finalOccurrences)
}
一旦完成,我必须更新我的代码以确保我始终使用我的结构化数据作为真实来源(我以前没有这样做,因为访问“源”平面数据通常更容易,而且我'我已经在我的列表视图中更新了我的 ForEach,以便仅在 deleted 为 false 时呈现一行。
它有效,这可能是解决问题的次优方法。 但没有更多的崩溃。 仍然有兴趣听到更好的方法来解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.