为了确保核心数据@FetchRequest变量动态运行,需要进行哪些代码更改(附加代码)?

时间:2019-10-28 11:59:15

标签: swift core-data swiftui

应该如何修改我的代码,以确保在添加新项目时在核心数据层发生异常时,SwiftUI不会继续显示新项目?

背景:当我运行下面的代码时,添加一个新项目执行“ context.save()”时出现异常,但是新项目请求确实失败了(未保存到Core Data),UI显示一个新项目。就像@FetchRequest行中的“ lists”变量没有动态地表现一样。

问题-如何修复代码以使应用程序正常运行?

代码:

import SwiftUI

struct ContentView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(fetchRequest: List.allListFetchRequest()) var lists: FetchedResults<List>

    private func addListItem() {
        let newList = List(context: context)
        newList.id = 1
        newList.title = "Testing 123"
        do {
            try context.save()
        } catch let e as NSError {
            print("Could not save new List. \(e.debugDescription)")
            return
        }

    }

    var body: some View {
        NavigationView {
            VStack {
                ForEach(lists) { list in
                    Text("List = \(list.title)")
                }
            }
            .navigationBarTitle( Text("My Todo Lists") )
            .navigationBarItems(
                trailing: Button(action: {self.addListItem()} ) {
                    Image(systemName: "plus.square")
                }
            )
        }
    }
}

示例输出:

Could not save new List. Error Domain=NSCocoaErrorDomain Code=133021 "(null)" UserInfo={NSExceptionOmitCallstacks=true, conflictList=(
    "NSConstraintConflict (0x600001fcccc0) for constraint (\n    id\n): database: (null), conflictedObjects: (\n    \"0x600000a7e360 <x-coredata:///List/t2F01130C-0D2A-4E88-A77D-A7BA0E921C213>\",\n    \"0xfb1bb528bb57810c <x-coredata://41B391F1-A95C-4971-9584-A2D3DFFF5380/List/p3>\"\n)"
)}

1 个答案:

答案 0 :(得分:0)

吉姆·多维(Jim Dovey)通过这个建议给了我前进的方向:

private func addListItem() {  
    context.performBlock { context in  
        let newList = List(context: context)  
        newList.id = 1  
        newList.title = "Testing 123"  
        do {  
            try context.save()  
        }  
        catch {  
            print("Failed to save new item. Error = \(error)")  
            context.delete(newList)  
            // don't need to save here, because we're in `performBlock` and have reverted the only unsaved change.  
        }  
    }  
}