CoreData: error: (14) I/O error for database

11,548

Solution 1

Now that the NDA on iOS7 has been lifted I can post for the sake of completion the workaround I found for this problem.

The Core Data in iOS7 uses by default WAL in the sqlite.

The only solution that did work was to create the sqlite using iOS6 simulator without WAL and import it in the project:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    static NSPersistentStoreCoordinator *psc;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        psc = [[NSPersistentStoreCoordinator alloc] 
                 initWithManagedObjectModel:self.managedObjectModel];
        NSURL *storeURL = [[NSBundle mainBundle] 
                  URLForResource:@"database" withExtension:@"sqlite"];
        [psc addPersistentStoreWithType:NSSQLiteStoreType
                          configuration:nil
                                    URL:storeURL
                                options:@{NSReadOnlyPersistentStoreOption : @YES,
                             NSSQLitePragmasOption: @{@"journal_mode":@"DELETE"}}
                                  error:NULL];
    });
    return psc;
}

Solution 2

NSURL *storeURL = [[NSBundle mainBundle] 
                     URLForResource:@"database" withExtension:@"sqlite"];

builds a path inside the application bundle, which is read-only. The persistent store file needs to reside in a writable directory, e.g. the "Documents" directory.

EDIT: The above answer is actually wrong, it is possible to open a read-only Core Data file from the application bundle (using NSReadOnlyPersistentStoreOption). The only thing I can currently imagine is that the bundled file is not a valid Core Data database. Adding the launch argument

-com.apple.CoreData.SQLDebug 1

might help to localize the problem.

Share:
11,548
ppaulojr
Author by

ppaulojr

25 years of programming experience. Objective-C,C,C++,Python,Lua and many others.

Updated on July 03, 2022

Comments

  • ppaulojr
    ppaulojr almost 2 years

    When compiling and running in the XCode a project using Core Data I'm getting an error I never saw before:

     2013-09-12 16:59:10.156 myapp[57811:70b] CoreData: error: 
          (14) I/O error for database at /Users/administrador/Library/
             Application Support/iPhone Simulator/7.0/Applications/
             6BA67336-B093-46CF-8B11-E3595409DAC2/myapp.app/database.sqlite.  
    
             SQLite error code:14, 'unable to open database file'
    

    The code that generates this message is:

        psc = [[NSPersistentStoreCoordinator alloc]
                       initWithManagedObjectModel:self.managedObjectModel];
        NSURL *storeURL = [[NSBundle mainBundle] 
                             URLForResource:@"database" withExtension:@"sqlite"];
        [psc addPersistentStoreWithType:NSSQLiteStoreType 
                 configuration:nil URL:storeURL 
                 options:@{NSReadOnlyPersistentStoreOption : @YES} error:NULL];
    

    I have tried Build->Clean, remove derived data, uninstall the app.

    I have checked this question before posting and I believe the problem is different.

    Note: The sqlite is a resource of the app

    The info using the debug suggested

    2013-09-12 17:43:38.341 myapp[58322:70b] CoreData: annotation: Connecting to sqlite database file at "/Users/administrador/Library/Application Support/iPhone Simulator/7.0/Applications/6BA67336-B093-46CF-8B11-E3595409DAC2/myapp.app/database.sqlite"
    2013-09-12 17:43:38.360 myapp[58322:70b] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
    2013-09-12 17:43:38.363 myapp[58322:70b] CoreData: annotation: Disconnecting from sqlite database due to an error.
    2013-09-12 17:43:38.364 myapp[58322:70b] CoreData: error: (14) I/O error for database at /Users/administrador/Library/Application Support/iPhone Simulator/7.0/Applications/6BA67336-B093-46CF-8B11-E3595409DAC2/myapp.app/database.sqlite.  SQLite error code:14, 'unable to open database file'
    2013-09-12 17:43:38.366 myapp[58322:70b] CoreData: annotation: Disconnecting from sqlite database.
    
  • cutsoy
    cutsoy over 10 years
    Though you're probably right, it is unusual that it's not able to open a read-only database from a read-only location.
  • ppaulojr
    ppaulojr over 10 years
    It always worked. I'm not sure why a read-only database must reside in Documents
  • Martin R
    Martin R over 10 years
    @ppaulojr: You are right (and I wrote this answer too quickly :-) - Could it be that the bundled file is not a valid Core Data database (matching the current model)?
  • Martin R
    Martin R over 10 years
    @ppaulojr: Perhaps add the launch argument "-com.apple.CoreData.SQLDebug 1" for more information.
  • ppaulojr
    ppaulojr over 10 years
    I added the info from SQLDebug
  • Martin R
    Martin R over 10 years
    @ppaulojr: Does it work if you copy the sqlite file to the Documents directory and open it from there? Can you open the file with the "sqlite3" command line tool? Does the problem occur on iOS 6 as well?
  • ppaulojr
    ppaulojr over 10 years
    it doesn't happen in iOS6
  • Martin R
    Martin R over 10 years
    @ppaulojr: (This is just an idea!) Have a look at the "What’s New in Core Data and iCloud" session from WWDC 2013. You can download the PDF file from developer.apple.com/wwdc/videos. Apple changed the default journaling mode for the SQLite file from "rollback" to "write-ahead logging". This should not matter for a read-only file, but on page 177 of that PDF file you see a option to restore the old behavior. You could try if that helps.
  • ppaulojr
    ppaulojr over 10 years
    I'll take a look and maybe we should hold the answer until 17th Sept.
  • Martin R
    Martin R over 10 years
  • mclin
    mclin about 10 years
    It's easier to just disable WAL like here: stackoverflow.com/a/18870738/288860
  • user1785227
    user1785227 over 8 years
    Thanks a lot for this, was looking for a solution online for ages. It's so frustrating that documentation for using a prepopulated read-only db in IOS is so lacking.