2013-06-26 3 views
0

Уточнение в «не доступной» SQL-базе данных: контекст/хранилище не может обнаружить какие-либо записи в .sqlite только на устройствах, несмотря на то, что NSBundle имеет .sqlite и размер файла правильного размера .sqlite. В симуляторе контекст/хранилище отлично работает.Основные данные на устройстве, не обращающемся к sqlite DB

Я нахожусь в тупике. Я добавил версию модели для своего xcdatamodeld. Я перезагрузил версию, чтобы мой код автоматически выполнял миграцию и заново заполнил мою базу данных.

На симуляторе iPhone он работает. Однако при запуске устройства он не считывает данные из базы данных.

Я поместил код, чтобы обнаружить, что sqllite на самом деле находится на устройстве, а также проверьте размер файла. SQLLite скопируется правильно из NSBundle, а также размер файла, указывающий на наличие данных.

Как-то мой код отказывается получить доступ к БД на устройстве. Любая идея, почему это так? Код для доступа к БД не изменился - единственное, что изменилось, - это датамодель. Приведенный ниже код работал на устройства до обновления.

// Returns the managed object context for the application. 
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
- (NSManagedObjectContext *)managedObjectContext 
{ 
if (_managedObjectContext != nil) { 
    return _managedObjectContext; 
} 

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
if (coordinator != nil) { 
    _managedObjectContext = [[NSManagedObjectContext alloc] init]; 
    [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 
} 
return _managedObjectContext; 
} 

// Returns the managed object model for the application. 
// If the model doesn't already exist, it is created from the application's model. 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (_managedObjectModel != nil) { 
    return _managedObjectModel; 
} 
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"sirona" withExtension:@"momd"]; 
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
return _managedObjectModel; 
} 

// Returns the persistent store coordinator for the application. 
// If the coordinator doesn't already exist, it is created and the application's store added to it. 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
if (_persistentStoreCoordinator != nil) { 
    return _persistentStoreCoordinator; 
} 

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"sirona.sqlite"]; 

NSString *databasePath = [NSBundle.mainBundle pathForResource:@"sirona" ofType:@"sqlite"]; 
NSLog(@"File manager: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[[NSBundle mainBundle] bundlePath] error:nil]); 
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath: @"sirona.sqlite" error: NULL]; 
UInt32 result = [attrs fileSize]; 
NSLog(@"File size: %d", (unsigned int)result); 
NSError *error = nil; 

// important part starts here 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, 
          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
                  nil]; 

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 

return _persistentStoreCoordinator; 
} 

Как я получить доступ к БД через основные данные:

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    [request setEntity:[NSEntityDescription entityForName:@"Representative" inManagedObjectContext:context]]; 
    [request setIncludesSubentities:NO]; //Omit subentities. Default is YES (i.e. include subentities) 

    NSError *err; 
    NSUInteger count = [context countForFetchRequest:request error:&err]; 
    NSLog(@"Count: %lu", (unsigned long)count); 

Edit: Не знаю, как это работает без кода, чтобы скопировать его на устройство. Но сейчас он работает.

код, чтобы сделать это:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"sirona.sqlite"]; 

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) { 
    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"sirona" ofType:@"sqlite"]]; 
    NSLog(@"PreloadURL: %@", preloadURL); 
    NSError* err = nil; 

    if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) { 
     NSLog(@"Oops, could copy preloaded data"); 
    } 
} 

NSError *error = nil; 
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
+0

Какая часть неудачников? Некоторые из этих 'NSLog' печатают нечто иное, чем вы ожидаете? «отказ от доступа» довольно расплывчато. –

+0

Извините, я немного уточню вопрос. Часть, которая не работает, фактически получает данные из .sqlite - в частности, она показывает 0 результатов для любых записей, которые я ищу в БД только на устройстве (тот же код работает для симулятора). Я не получаю никаких сбоев, и NSLogs проверяют, что .sqlite существует (и в нем есть данные). Это я проверял, чтобы убедиться, что .sqlite становится связанным при архивировании. – LyricalPanda

+0

Я не вижу '[_persistentStoreCoordinator addPersistentStoreWithType: ...]' вызов в вашем коде, где файл sqlite в 'storeURL' прикреплен к координатору магазина! (Но если бы этот код был действительно пропущен, как и на симуляторе тоже :-) –

ответ

0

Вы должны скопировать файл SQLite на папку, в которой вы Hare разрешения чтения/записи до инициализации контекста CoreData

+0

В managedObjectContext я создаю координатор перед выделением и инициализацией ObjectContext.Таким образом, похоже, что файл sqlite копируется до создания контекста. Как я могу проверить, есть ли в папке, в которой она написана, разрешения на чтение/запись? – LyricalPanda

+0

глядя на ваш код, вы все еще ссылаетесь на файл в MainBundle ... так что ваш файл sqlite является файлом readonly, вы копируете файл вручную в вас NSHomeDirectory()/Ducuments ... или что-то в этом роде – Manu