Reputation: 5413
Aw geez! I screwed something up!
I'm a Core Data noob, working on my first iOS app. After much Stack Overflowing I'm using this code:
NSString *path = [[NSBundle mainBundle] pathForResource:@"CoreData" ofType:@"momd"];
if (!path) {
path = [[NSBundle mainBundle] pathForResource:@"CoreData" ofType:@"mom"];
}
NSAssert(path != nil, @"Unable to find Resource in main bundle");
CoreData is the name of my app.
I've tried to put in initial data into the app by finding the path to the sqlite file in my iPhone simulator, and then going and inserting into that sqlite file. But at some point, I moved the sqlite (thinking it would create a fresh copy), deleted the app from the simulator, and the sqlite file is gone. I'm not sure if I'm leaving out some part of the process (this was a few hours ago) but the end result is that everything is screwed up.
How do I resubstantiate this sqlite / momd file? "Clean" and "Clean all targets" are grayed out.
I'm happy to post the relevant code from my app that would help shed some light on this problem but there's tons of code relating to Core Data which I don't understand, so I'm not sure what part to post! Any help is greatly appreciated.
Upvotes: 20
Views: 25874
Reputation: 9767
If you added a version to your model, change .mom to .momd
NSString *path = [[NSBundle mainBundle] pathForResource:@"CoreData" ofType:@"momd"];
if (!path) {
path = [[NSBundle mainBundle] pathForResource:@"CoreData" ofType:@"momd"];
Upvotes: 2
Reputation: 1840
I found it very valuable to go look at my executable in the simulator "disk image".
If you head into ~/Library/Application Support/iPhone Simulator//Applications, you can see the apps on the phone. Figure out which one is yours (use find, or look at the date), and then browse into your target.app and look for the .momd file.
In my case, my momd name was different from my .xcdatamodeld file name, which was why core data couldn't load it. Once I corrected the name in the AppDelegate things started working correctly.
Note that the momd "file" seems to actually be a directory (like the .app setup).
--
In terms of adding the code to initialise core data; I did this too. I created a new blank project with core data enabled, and copied over all the initialisation steps for core data in the AppDelegate file. There's a whole bunch of stuff related to initialising the whole stack, so if that is not present, you need to put it there.
Upvotes: 4
Reputation: 358
If the clean targets menu items are grey, it could be that you have the app running.
The way you're getting the path to the mom/momd looks like you've tried to integrate CoreData after the fact (rather than opting to have it included when you created the project). I had the same issues as you probably do. The default code that looks for momd assumes it exists, and you should be able to, as well, if you add a version of your data model to the project.
To do that, select the xcdatamodel file, and in the Design menu select Data Model > Add Model Version. Then, you'll have CoreData.xcdatamodeld with a subtree containing Coredata.xcdatamodel and a new version. You can just delete the extra version and you'll have the hierarchy you need. If you build and look in the App bundle, you'll see the CoreData.momd directory with the mom inside.
Those steps aren't included in any of the CoreData tutorials I've found so far. I hope it's helpful!
Upvotes: 18
Reputation: 34185
Here are a few recommendations:
The code you posted to get the .mom(d)
file is not exactly the recommended way. Use mergedModelFromBundles
instead, as in
self.managedObjectContent= [NSManagedObjectModel mergedModelFromBundles:nil];
It takes care of getting the path, choosing/merging the correct mom
or momd
, and initializing of the MOC all by one step. You should use this. But note that you need to clean the build process once in a while, as discussed in this SO question/answer.
This shows that, although crawling through StackOverflow is often good, that's not the best approach when you deal with a big framework like CoreData.
Honestly, take a day and read the documentation from the start to the end. You might want to google bits of code and to start coding immediately, but reading through the documentation definitely saves the development time considerably in the long run.
Also, Marcus Zarra's CoreData book (see here) helped me a lot. It might look expensive, but it was totally worth while.
On a different topic, I don't think it a good strategy to put the pre-cooked sqlite file into the simulator's directory (inside ~/Library/Application Support/iPhone Simulator/
) even for development purpose... because it doesn't work on the real device. If you need to do so, put the sqlite file as a resource of the app, and copy it at the launch time to either Documents
or Caches
, and use that afterwards.
Upvotes: 45
Reputation: 1196
Practical answer: You might try the following code if you're having path issues. You'll also want to check that your xcdatamodel file is included as a resource for your target.
[[NSBundle bundleForClass:[self class]] pathForResource:@"CoreData" ofType:@"momd"]
Better answer: There's a distinction between a momd file, which represents your NSManagedObjectModel, and a sqlite file, which is used by your NSPersistentStore object. The best approach to working with CoreData is to let the SDK handle all the interaction with sqlite. The only thing you should need to set up regarding sqlite is telling your NSPersistantStore where to stash your sqlite file. The managed objects that you define in your managed object model will handle all the data insertion and updates for you.
If you're not familiar with the objects I've referenced, check out the apple docs for a very helpful overview. You'll definitely want to take the time to grasp the full CoreData stack, as the time investment will pay off in far less headaches if you work with Core Data the way Apple expects. It is a more abstracted design than many web developers are accustomed to, but trying to circumvent that abstraction by working directly with SQLite creates its own set of complexity.
Upvotes: 7