开发者

sqlite db creation issue

Im teaching myself objective-c and currently trying to work out how to integrate a 开发者_开发知识库database into my application. Ive looked at many example, forums and tutorial but none have worked, what am i doing wrong?

  1. Most of the examples come ready with a [projectName].sqlite db in the application. How does that get added? Not seen one explanation of how that ends up in the project.

  2. I've created my Object Model and classes. Im running a method which checks if DB exists, if not, it creates the db. Ive found several examples where different paths are used and im not sure which is correct, Some examples copied part of my project files into the documents/mainDatabase.sqlite folder! Is the following correct, if so why am i getting an error?

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to create writable database file with message 'The operation couldn’t be completed. No such file or directory'.

Using these causes the above error, and yes the defaultDBPath does exist

defaultDBPath: /Users/myuser/Library/Application Support/iPhone Simulator/4.2/Applications/DFBAD921-CEBF-471E-B98B-04FDF2620146/Documents

defaultDBPath: /Users/myuser/Library/Application Support/iPhone Simulator/4.2/Applications/DFBAD921-CEBF-471E-B98B-04FDF2620146/Documents/mainDatabase.sqlite

writableDBPath: /Users/myuser/Library/Application Support/iPhone Simulator/4.2/Applications/DFBAD921-CEBF-471E-B98B-04FDF2620146/dbProj12.app/mainDatabase.sqlit

- (void)createEditableCopyOfDatabaseIfNeeded {
// First, test for existence - we don't want to wipe out a user's DB
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentDirectory = [self applicationDocumentsDirectory];
NSLog(@"documentDirectory = %@", documentDirectory);
NSString *writableDBPath = [documentDirectory stringByAppendingPathComponent:@"iBountyHunter.sqlite"];

NSLog(@"defaultDBPath = %@", writableDBPath);
BOOL dbexits = [fileManager fileExistsAtPath:writableDBPath];
if (!dbexits) {
    // The writable database does not exist, so copy the default to the appropriate location.
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"iBountyHunter.sqlite"];

    NSLog(@"defaultDBPath = %@", defaultDBPath);
    NSError *error;
    BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}

}

Look forward to your reply.


I'm assuming you are using CoreData, but the solution should be valid for every database type.

The message stated that iBountyHunter.sqlite doesn't exists and it's a true message: that db should be added in the XCode project and packaged when you build the app.

Some apps ships with an already populated database probably modified by the developer on the mac, based on what is created in the simulator (or even in a development device).

  1. Build and run you app on the simulator;
  2. Look in the Documents folder on your device and copy the database;
  3. Edit it adding custom data;
  4. Add the db to XCode;
  5. Add the code you've reported;
  6. Build and let the app copy the populated database on the device.


It might be late, but i wanted to answer this question so that in future no one gets this issue.

The answer has to do with the "Target Membership".

  • click on the sql file in the left-pane of Xcode

  • Under "Target Membership", make sure the "check" is "checked" for your target build.

that's it, this solves my issue. I hope this helps you also.


Mac makes a good point, are you using sqlite or core data?

If you are using sqlite then one of the easier things to do is on application launch, copy it into your apps documents directors (unless it already exists of course, in which case do nothing)

I generally create an sqliteDB external to xcode and add it as a file (just like an image). Then in the 'applicationDidFinishLaunchingWithOptions' method (in your app delegate I call the same method, but my code is a little different. Take a look:

- (void)createEditableCopyOfDatabaseIfNeeded 
{
    //We always need to overwrite the DB, but first we need to extract usedQuestionIds, ObjectiveData and stats

    //Once database is replaced, reinsert data

    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"yourdatabasename.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success)
    {
        //might want to check for update and if so, back up users unique data, replace database and reinsert
    }
    else
    {
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"yourdatabasename.sqlite"];
        [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    }

It then create another method in my app delegate that allows me to get a db connection which I can then use:

+(sqlite3 *)getNewDBConnection
{
    sqlite3 *newDBconnection;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yoursqliteDatabaseName.sqlite"];
    // Open the database. The database was prepared outside the application.
    if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) 
    {

        NSLog(@"Database opened successfully");

    } 
    else 
    {
        NSLog(@"Error in opening database  ");
    }

    return newDBconnection; 

}

Now wherever you are in your app you can get a connection to you db by calling:

sqlite3 *db = [YourAppDelegateName getNewDBConnection];

//do stuff with your sqlite db connection

sqlite3_close(db);

Hope that helps :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜