I'm just trying to save a relationship in Core Data using SwiftUI.
`TodoListView`:
struct TodoListView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: TodoList.entity(),
sortDescriptors: [NSSortDescriptor(key: "order", ascending: true)]
) var todoLists: FetchedResults<TodoList>
@State var add = false
@State var edit = false
var body: some View {
NavigationView {
List {
ForEach(todoLists, id: \.self) {todoList in
NavigationLink(destination: TodoItemView(todoList: todoList), label: {
Text(todoList.title!).foregroundColor(stringToColor(string: todoList.color!))
})
}
}
...
This creates navigation links for each todo list. The todo list is passed to the todo item view.
`TodoItemView`:
struct TodoItemView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Environment(\.managedObjectContext) var managedObjectContext
@State var add = false
var todoList: TodoList
var body: some View {
List {
ForEach(todoList.todoItems!, id: \.self) {todoItem in
Text(todoItem.title!)
}
}
.navigationBarTitle(todoList.title!)
.navigationBarItems(trailing:
HStack(spacing: 15) {
Button(action: {
self.add = true
}, label: {
Image(systemName: "plus")
.imageScale(.large)
.foregroundColor(todoList.color == "None" ? .accentColor : .primary)
}).sheet(isPresented: $add, content: {
AddTodoItemView(todoList: self.todoList)
.environment(\.managedObjectContext, self.managedObjectContext)
})
...
This is supposed to list all of the todo items for the todo list. When you click on the plus image in the navigation bar, it loads a modal for adding a new todo item, and passes the todo list to it.
I should note that `todoList.todoItems` is set up as `@NSManaged public var todoItems: [TodoItem]?` in my `TodoList` entity class. I've also set it up as a one-to-many relationship in Core Data.
`AddTodoItemView`:
struct AddTodoItemView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Environment(\.managedObjectContext) var managedObjectContext
@State var title = ""
var todoList: TodoList
var body: some View {
NavigationView {
Form {
Section {
TextField("Title", text: $title)
}
Section {
Button(action: {
self.save()
self.presentationMode.wrappedValue.dismiss()
}, label: {
Text("Save")
})
}
}
.navigationBarTitle("Add Todo Item", displayMode: .inline)
}
}
func save() {
self.title = self.title.trimmingCharacters(in: .whitespaces)
if (self.title.count > 0) {
let todoItem = TodoItem(context: managedObjectContext)
todoItem.title = self.title
todoItem.order = (self.todoList.todoItems?.last?.order ?? 0) + 1
todoList.addToTodoItems(todoItem)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}
}
...
The `save()` function here is what causes the error and crashes the app.
I'm not sure I'm doing this correctly. Is this the right way to list and save a relationship? All I want to do is add the new todo item to the todo list. I'm having a hard time grasping working with relationships in SwiftUI.
Here is the complete result of `print(error)`:
2019-11-09 00:02:43.989211-0500 ColorTodo4[10656:682980] [Snapshotting] Snapshotting a view (0x7ff3dfd310e0, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2019-11-09 00:02:57.142381-0500 ColorTodo4[10656:682980] [Snapshotting] Snapshotting a view (0x7ff3dff10a20, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2019-11-09 00:03:08.307765-0500 ColorTodo4[10656:682980] [Snapshotting] Snapshotting a view (0x7ff3dfd307e0, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2019-11-09 00:03:24.827731-0500 ColorTodo4[10656:682980] [Snapshotting] Snapshotting a view (0x7ff3dfe7ca10, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2019-11-09 00:03:40.275685-0500 ColorTodo4[10656:682980] [Snapshotting] Snapshotting a view (0x7ff3dfd3cb80, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.
2019-11-09 00:03:41.202375-0500 ColorTodo4[10656:682980] -[__NSCFSet objectAtIndex:]: unrecognized selector sent to instance 0x60000228d3e0
2019-11-09 00:03:41.207166-0500 ColorTodo4[10656:682980] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet objectAtIndex:]: unrecognized selector sent to instance 0x60000228d3e0'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c6ff94 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x00007fff23c53dac ___forwarding___ + 1436
4 CoreFoundation 0x00007fff23c55f38 _CF_forwarding_prep_0 + 120
5 libswiftCore.dylib 0x00007fff5105b79e $ss12_ArrayBufferV19_getElementSlowPathyyXlSiF + 142
6 libswiftCore.dylib 0x00007fff5105e6ea $sSayxSicir + 202
7 libswiftCore.dylib 0x00007fff5105ede8 $sSayxGSlsSly7ElementQz5IndexQzcirTW + 56
8 SwiftUI 0x00007fff2c4933a1 $s7SwiftUI7ForEachV11IDGeneratorO6makeID4data5index6offsetq_x_5IndexQzSitF + 289
9 SwiftUI 0x00007fff2c4963e1 $s7SwiftUI19DynamicContentState33_4103B39A1695DB4F1CFCE0B3FB46910FLLC4item2at6offsetAD4ItemCyxq_q0__G5IndexQz_SitF + 865
10 SwiftUI 0x00007fff2c497042 $s7SwiftUI19DynamicContentState33_4103B39A1695DB4F1CFCE0B3FB46910FLLC20fetchViewsPerElementSiSgyF + 466
11 SwiftUI 0x00007fff2c497dbc $s7SwiftUI19DynamicContentState33_4103B39A1695DB4F1CFCE0B3FB46910FLLC7viewIDsAA12_ViewList_IDV5ViewsCSgvg + 188
12 SwiftUI 0x00007fff2c49a732 $s7SwiftUI18DynamicContentList33_4103B39A1695DB4F1CFCE0B3FB46910FLLV5countSivgTm + 18
13 SwiftUI 0x00007fff2c49acb3 $s7SwiftUI18DynamicContentList33_4103B39A1695DB4F1CFCE0B3FB46910FLLVyxq_q0_GAA04ViewE0A2aFP5countSivgTWTm + 51
14 SwiftUI 0x00007fff2c504f59 $s7SwiftUI14MergedViewList33_70E71091E926A1B09B75AAEB38F5AA3FLLV7viewIDsAA01_dE3_IDV5ViewsCSgvg + 217
15 SwiftUI 0x00007fff2c601d16 $s7SwiftUI8SectionsV4from10useFootersAcA22_VariadicView_ChildrenV_SbtcfC + 70
16 SwiftUI 0x00007fff2c203ab9 $s7SwiftUI20SystemListDataSourceV_5style12minRowHeight0h6HeaderJ0ACyxGAA22_VariadicView_ChildrenV_So07UITableM5StyleV12CoreGraphics7CGFloatVSgANtcfC + 105
17 SwiftUI 0x00007fff2c203e8a $s7SwiftUI9PlainListV11BodyContentV4bodyQrvg + 506
18 SwiftUI 0x00007fff2c203f49 $s7SwiftUI9PlainListV11BodyContentVyx_qd__GAA4ViewA2aGP4body0E0QzvgTW + 9
19 SwiftUI 0x00007fff2c0613c7 $s7SwiftUI19DynamicPropertyBody33_9F92ACD17B554E8AB7D29ABB1E796415LLV6update7contexty14AttributeGraph0P7ContextVyADyxGGz_tF + 1671
20 SwiftUI 0x00007fff2c061bf0 $s7SwiftUI19DynamicPropertyBody33_9F92ACD17B554E8AB7D29ABB1E796415LLVyxG14AttributeGraph07UntypedN0AafGP7_update_5graph9attributeySv_So10AGGraphRefaSo11AGAttributeatFZTW + 32
21 AttributeGraph 0x00007fff2f8bbc69 $sTA + 25
22 AttributeGraph 0x00007fff2f8a3ac5 _ZN2AG5Graph11UpdateStack6updateEv + 1111
23 AttributeGraph 0x00007fff2f8a3d83 _ZN2AG5Graph16update_attributeEjb + 377
24 AttributeGraph 0x00007fff2f8a89a1 _ZN2AG8Subgraph6updateEj + 929
25 SwiftUI 0x00007fff2c19a4a0 $s7SwiftUI9ViewGraphC14runTransaction33_D63C4EB7F2B205694B6515509E76E98BLL2inySo10AGGraphRefa_tF + 224
26 SwiftUI 0x00007fff2c19a270 $s7SwiftUI9ViewGraphC17flushTransactionsyyFySo10AGGraphRefaXEfU_ + 256
27 SwiftUI 0x00007fff2c199f0f $s7SwiftUI9ViewGraphC17flushTransactionsyyF + 223
28 SwiftUI 0x00007fff2c19a08f $s7SwiftUI9ViewGraphC16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_yACXEfU_ + 15
29 SwiftUI 0x00007fff2c198219 $s7SwiftUI9ViewGraphCIgg_ACytIeggr_TR03$s7a3UI9cD92C16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_yACXEfU_Tf3nnpf_n + 9
30 SwiftUI 0x00007fff2c4e0817 $s7SwiftUI16ViewRendererHostPAAE06updateC5Graph4bodyqd__qd__AA0cG0CXE_tlF + 71
31 SwiftUI 0x00007fff2c4e07c3 $s7SwiftUI14_UIHostingViewCyqd__GAA0D13GraphDelegateA2aEP06updatedE04bodyqd__qd__AA0dE0CXE_tlFTW + 19
32 SwiftUI 0x00007fff2c19a06a $s7SwiftUI9ViewGraphC16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_ + 122
33 SwiftUI 0x00007fff2c1b7cec $sIeg_ytIegr_TR + 12
34 SwiftUI 0x00007fff2bffc051 $sIeg_ytIegr_TRTA + 17
35 SwiftUI 0x00007fff2bffbf77 $sSo9NSRunLoopC7SwiftUIE14flushObserversyyFZ + 119
36 SwiftUI 0x00007fff2bffbef9 $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_ + 9
37 SwiftUI 0x00007fff2bffbfeb $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_To + 43
38 CoreFoundation 0x00007fff23bb1617 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
39 CoreFoundation 0x00007fff23bac0ae __CFRunLoopDoObservers + 430
40 CoreFoundation 0x00007fff23bac72a __CFRunLoopRun + 1514
41 CoreFoundation 0x00007fff23****16 CFRunLoopRunSpecific + 438
42 GraphicsServices 0x00007fff38438bb0 GSEventRunModal + 65
43 UIKitCore 0x00007fff4784fb68 UIApplicationMain + 1621
44 ColorTodo4 0x0000000107668d2b main + 75
45 libdyld.dylib 0x00007fff51a1dc25 start + 1
46 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Why is this happening and how do I fix it?