2014-01-28 98 views
0

我有一個應用程序,旨在與預填充SQLite數據庫。我將把這個數據庫包含在這個包中。如何修改委託以使用該數據庫而不是生成新的數據庫?如何使OSX應用程序在包中使用sqlite數據庫?

這是我第一次在OSX上認真的應用程序。

在委託目前的方法是像現在這樣的權利:

// Returns the directory the application uses to store the Core Data store file. This code uses a directory named "com.addfone.LoteriaMac" in the user's Application Support directory. 
- (NSURL *)applicationFilesDirectory 
{ 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject]; 
    return [appSupportURL URLByAppendingPathComponent:@"com.myApp.BotMax"]; 
} 

// Creates if necessary and returns the managed object model for the application. 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (_managedObjectModel) { 
     return _managedObjectModel; 
    } 

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"BotMax" withExtension:@"momd"]; 
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
    return _managedObjectModel; 
} 

// Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.) 


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator) { 
     return _persistentStoreCoordinator; 
    } 

    NSManagedObjectModel *mom = [self managedObjectModel]; 
    if (!mom) { 
     NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd)); 
     return nil; 
    } 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSURL *applicationFilesDirectory = [self applicationFilesDirectory]; 
    NSError *error = nil; 

    NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:@[NSURLIsDirectoryKey] error:&error]; 

    if (!properties) { 
     BOOL ok = NO; 
     if ([error code] == NSFileReadNoSuchFileError) { 
      ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error]; 
     } 
     if (!ok) { 
      [[NSApplication sharedApplication] presentError:error]; 
      return nil; 
     } 
    } else { 
     if (![properties[NSURLIsDirectoryKey] boolValue]) { 
      // Customize and localize this error. 
      NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]]; 

      NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 
      [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey]; 
      error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict]; 

      [[NSApplication sharedApplication] presentError:error]; 
      return nil; 
     } 
    } 

    NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"BotMax.storedata"]; 
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; 
    if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) { 
     [[NSApplication sharedApplication] presentError:error]; 
     return nil; 
    } 
    _persistentStoreCoordinator = coordinator; 

    return _persistentStoreCoordinator; 
} 

數據庫文件被命名爲喜歡BotMax.sqlite

感謝。

回答

3

發佈預填充SQLite數據庫的最簡單方法是在persistentStoreCoordinator初始化之前將.sqlite文件複製到Application Support文件夾中。

下面的代碼只是複製捆綁的數據庫。在使用該方法之前需要考慮一些事項:

  • 這種簡單的方法只複製初始數據塊一次。
  • 它不考慮合併或遷移現有門店(例如,當你船的更新與變化的模型)
  • 核心數據是使用一個新的journal_mode因爲iOS的7 & OS X 10.9。該模式在保存數據庫時創建一個附加文件。 (* .sqlite-WAL)。如果創建的程序您預先填充的SQLite文件與OS X 10.9/iOS 7或更高版本的SDK相關聯,那麼您還必須運送.sqlite-wal文件。
  • 或者,您可以禁用在通過傳遞@{ NSSQLitePragmasOption : @{ @"journal_mode" : @"DELETE" } };作爲選項字典以addPersistentStoreWithType

創建您的預填充DB下面的代碼是基於非標準的Xcode模板的應用程序的WAL日誌模式-document基於核心數據應用:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator) { 
     return _persistentStoreCoordinator; 
    } 

    NSString* dbFilename = @"BotMax.sqlite"; 
    NSURL* initialDBURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:dbFilename]; 
    NSURL* workingDBURL = [[self applicationFilesDirectory] URLByAppendingPathComponent:dbFilename]; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 
    NSURL* applicationFilesDirectory = [self applicationFilesDirectory]; 
    NSError* error = nil; 

    if(![fileManager fileExistsAtPath:[workingDBURL path]]) 
    { 
     BOOL result = [fileManager copyItemAtURL:initialDBURL toURL:workingDBURL error:&error]; 
     if(!result) 
     { 
      [[NSApplication sharedApplication] presentError:error]; 
      return nil; 
     } 
    } 
    ... 
} 

objc.io問題#4具有約出貨預填充核心數據存儲部分:http://www.objc.io/issue-4/importing-large-data-sets-into-core-data.html

+0

我已經使用了你的解決方案,對我來說工作正常,但是當我編譯應用程序並將可執行文件發送給另一個人時,它會崩潰,並顯示消息「找不到BotMax.sqlite」。我有三重檢查,數據庫位於軟件包上,並在「複製資源」選項卡上列出。 – SpaceDog

相關問題