|
I am struggling with Core Data and SwiftUI to the point that it is causing some crashes in my app I cannot explain. Looking in it, it always comes down to creating a core data entry as part of a sheet popping up and somehow the context seems wrong. In my MainApp:App I do have
In ContentView I do have
Now I could save the object in two ways as part of a sheet I do pop up (to which I add the
To me that should not make any difference, whether I am using But it looks like there is a difference. Is it better to save a new object directly and as quickly as possible (i.e. as part of the same sheet) rather than relying on a generic routine in DataController that saves the context? Any help appreciated. |
|
First, do these crashes happen on the Simulator or on a real device? My experience with "unmotivated" crashing with no hint whatsoever (the usual BAD_EXEC) is that it happens only on the simulator in context with SwiftUI. When I test it on a real device I can't reproduce these crashes. Second, I think your approach is somehow redundant. For myself, I pass only the dataController and I have a variable
on my dataController for easier access. |
|
Thanks, Crashes happen on real devices; my app is life and from the limited crash reports I can see in Xcode, the error is mostly related to creating a new core data object as part of a sheet. I myself cannot reproduce the crash one way or another which makes it difficult to tackle. It almost feels like a timing issue; saving in the sheet using viewContext.save() is quicker then going out to the generic persistence controller (in my case dataController); as if that takes longer and the app is losing reference. I bumped on this documentation from Apple https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/MO_Lifecycle.html about creating a strong reference between managed objects and context but I am not sure whether that is the right path to go into... |
|
I guess you pass the dataController or the context with the environment to the sheet? I would try to pass the dataController/context in the initializer to the sheet and store it in a local variable and look if the problem persists. I for myself struggle with the lifecycle of the SwiftUI views and their sometimes irratic behaviour (not to mention sometimes it's just the simulator) and went for this approach and I don't experience problems like that anymore. I don't know if this fixes it for you but it would be a way to test it. |
|
|
|
Yes. My experience with the environment is not as good as it's with an initializer. Even if it's not the SwiftUI way. The problem I have with SwiftUI is that the lifecycle is sometimes not the way I expect it. See this thread for example. https://www.hackingwithswift.com/forums/swiftui/how-to-show-a-sheet-splash-screen-only-on-first-time-app-launch-when-the-user-presses-ok-the-splash-screen-should-never-be-seen-in-subsequent-launches/9594 I would expect that the UserDefaults/AppStorage is all initialized before any method in the body property is executed, but it isn't. At least at first start of the app. So I go with the init() as Xcode yells at me if I access something which doesn't have a value before I use it. |
|
I'm wondering if you are passing managedObjectContext into the sheet's own environment like:
This is how I usually handle sheets, so I am not sure if the sheet can sometimes pull the managedObjectContext from ContextView's environment and sometimes not. This is discussed here: https://www.hackingwithswift.com/books/ios-swiftui/creating-books-with-core-data Specifically this part:
|
SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.
Sponsor Hacking with Swift and reach the world's largest Swift community!
This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.