4
votes

I had some problems after starting a new coredata project with the xcode 3.2.5... my previous projects with core data (in previous xcode) worked fine, so I dont know what is the difference??

so the error I get when I build and go to the view that calls the core data is>

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '***  -[NSURL initFileURLWithPath:]: nil string parameter'

the strange thing is that in my *AppDelegate.m, in (edited thanks Rog but still not working!)

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (persistentStoreCoordinator_ != nil) {
    return persistentStoreCoordinator_;
}   

NSString *storePath = [[self applicationDocumentsDirectory]   stringByAppendingPathComponent: @"staff.sqlite"];

NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; //new position for the storeUrl!    

// Put down default db if it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"staff" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}

in the

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"staff.sqlite"];

I get the warning

NSURL may not respond to '-stringByAppendingPathComponent'

I option + click this stringByAppendingPathComponent and get (Symbol not found!!!!)

but in other projects I do option + click in the same and get the definition!!

  • so is this warning related to my error??
  • how to fix it???

Edit, included this in my viewDidLoad

NSLog(@"path= %@", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]) ;

which gives me in console:

path= /Users/mkss9/Library/Application Support/iPhone Simulator/4.2/Applications/2F364C20-2B87-4ABB-AA3E-FB6F7C15096F/Documents

please!, Im getting crazy !!

thank you!

3

3 Answers

7
votes

Some SDK Version ago (I don't know for sure when they did) apple changed the return type of applicationDocumentsDirectory in their project templates.

When you create a new project it looks like this:

/**
 Returns the URL to the application's Documents directory.
 */
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

in older templates it looked like this:

/**
 Returns the path to the application's documents directory.
 */
- (NSString *)applicationDocumentsDirectory {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}

and in between those two it looked like this:

/**
 Returns the path to the application's Documents directory.
 */
- (NSString *)applicationDocumentsDirectory {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

So you have to be careful, because all the old code that relies on applicationDocumentsDirectory returning a NSString won't work with newer templates.

And you can't just replace the new version with the older version because this would result in a change in your core data methods.

So I would suggest you to write your own method for returning the documents directory. Apple changes their applicationDocumentsDirectory quite often.

1
votes

I would imagine it's because -applicationDocumentsDirectory returns an NSURL * instead of an NSString *.

0
votes

Firstly you need to make sure you applicationDocumentsDirectory method is returning a NSString.

Once that's out of the way, the subsequent crash is because you are passing a path and filename that don't exist yet.

So if you move your NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; to after the code that checks for an existing file and puts a default one in case it doesn't exist, it should solve your problem.