Can't find momd file: Core Data problems

25,055

Solution 1

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.

Solution 2

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!

Solution 3

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.

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html#//apple_ref/doc/uid/TP40001650-TP1

Solution 4

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.

Solution 5

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"];
Share:
25,055
thekevinscott
Author by

thekevinscott

Slinging codes and flipping design burgers. Author of Deep Learning In Javascript (http://dljsbook.com)

Updated on July 10, 2022

Comments

  • thekevinscott
    thekevinscott almost 2 years

    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.

  • ncases
    ncases about 13 years
    This worked for me. I had added CoreData after the fact and was getting the "nil model" error because I didn't have a mom(d) in my build. Doing the "Add Model Version" (+ deleting the duplicate version) did the trick!
  • meddlingwithfire
    meddlingwithfire over 12 years
    This solved my issue. I had copy+pasted from the examples, and filled in what I thought was the correct momd file name. Turns out the filename was different that what I thought. +1
  • lhunath
    lhunath over 11 years
    I don't think you should say it "chooses" anything and certainly doesn't initialize a MOC. All it does is find all the models in given bundles and merges them. There is also nothing wrong with specifying the model URL if you don't need to merge multiple models. Apple explicitly proposes this and the clean option as solutions for this specific issue in the CD programming guide.
  • Teetotum
    Teetotum over 11 years
    In Xcode 4 you add a new version by selecting Editor -> Add Model Version.
  • Joel Martinez
    Joel Martinez over 11 years
    This did it for me, I had done a merge which for some reason removed the xcdatamodel file from the list of resources being copied with the app.
  • pnizzle
    pnizzle almost 11 years
    @lhunath I have been researching on Core Data and I'll confirm that Apple indeed says: initWithContentsOfURL: is the generally-preferred technique. Thanks Yuji for the link to the book. Might get that.
  • keegan3d
    keegan3d over 9 years
    This is exactly the missing piece I've been searching for that other tutorials have not mentioned! Thank you!
  • Jeff
    Jeff almost 9 years
    If your app is built with different teams using separate MOMs for different parts of the app, you certainly do not want to merge all models found in the main bundle for one particular context! They will become entangled unnecessarily. Also, Apple's Core Data Programming Guide in "Initializing the Core Data Stack" section shows passing NSURL from NSBundle URLForResource:withExtension: into NSManagedObjectModel initWithContentsOfURL:. This may have been a fine answer for 2010, but it might be leading devs astray in 2015.
  • Daniel
    Daniel over 7 years
    In my experience, sometimes cleaning alone does not work and I have to restart Xcode and / or delete the content of ~/Library/Developer/Xcode/DerivedData