2013-01-18 24 views
5

Próbuję wczytać trwały magazyn w aplikacji opartej na UIManagedDocument, aby poradzić sobie z podstawowymi danymi.iOS UIManagedDocument: nie można otworzyć wstępnie załadowanego magazynu trwałego

Persistent sklep próbuję użyć w aplikacji B, jest „generowane” i wypełniane dzięki aplikacji A. W obu aplikacji A i B używam obsługi UIManagedDocument z Justinem Driscoll (available here, dzięki Mister Driscoll!). Wszystko działa idealnie w aplikacji A.

Na podstawie techniki objaśnionej w tym temacie: Pre-load core data database in iOS 5 with UIManagedDocument, Próbuję umieścić magazyn trwały w pakiecie aplikacji B, i w razie potrzeby skopiować ten magazyn w folderze dokumentów (jeśli nie Sporządzono przed) w init tuż przed utworzeniem instancji.

Kopiowanie z pakietu do dokumentów jest ok (próbowałem innej metody i sprawdziłem tworzenie dzięki finderowi i nslog), ale po prostu nie mogę otworzyć "dokumentu". Aplikacja się nie zawiesza, widoki są wyświetlane, ale tabele są puste (używam dokładnie tego samego kodu co aplikacja A, z tym samym plikiem fetchedResultsController). Najpierw myślałem, że skopiowany stały magazyn jest pusty, wtedy zdałem sobie sprawę, że po prostu nie mogę poprawnie otworzyć dokumentu/skopiowanego trwałego sklepu) => Stan dokumentu = 5, co oznacza błąd UIDocumentStateClosed i UIDocumentStateSavingError (jeśli poprawnie to interpretuję? ?)

(Uwaga: próbowałem również do wystąpienia i otwórz dokument bezpośrednio z wiązki i mam ten sam problem: stan doc = 5)

Więc ... Trzy dni walki z ten stan dokumentu = 5 i nie mam pojęcia, co naprawić

Wyobrażam sobie, że coś jest nie tak z plikiem, który umieściłem w pakiecie aplikacji B (obecnie przeciągam i upuszczam z finder do xcode z zaznaczoną opcją "Utwórz odniesienia do folderów dla dowolnych dodanych folderów" Może chodzi o niektóre opcje, metadane, uprawnienia do plików lub ...

Czy masz jakieś pojęcie o tym, co zbadać?

(Nie sądzę, że chodzi o następujący kod, ale dobrze ...) Oto jak I init (na podstawie handlerka Justin Driscoll.) Tylko custo: sprawdzam, czy w folderze dokumentów znajduje się pakiet sklepu, nie tworzę go na podstawie pliku w wiązce)

- (id)init 
{ 
self = [super init]; 
if (self) { 
    self.document = nil; 

    NSLog(@"--- INIT ---"); 

    // On vérifie si il y a un dossier "My-Default-Document-As-Database" (notre persitent store) dans le dossier "Documents" 

    NSString *docDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString *docFolderPath = [docDirectory stringByAppendingPathComponent:@"My-Default-Document-As-Database"]; 

    if (![[NSFileManager defaultManager] fileExistsAtPath:docFolderPath]) { 
     NSError *error = nil; 
     NSLog(@"Pas de fichier trouvé à l'adresse docFolderPath, on va donc y créer notre persistent store"); 

     // COPY FROM BUNDLE 

     NSFileManager *fileManager = [NSFileManager defaultManager]; 

     NSString *DB = [docFolderPath stringByAppendingPathComponent:@"StoreContent"]; 

     [fileManager createDirectoryAtPath:DB withIntermediateDirectories:YES attributes:nil error:&error]; 

     NSLog(@"create directory error: %@",error); 

     DB = [DB stringByAppendingPathComponent:@"persistentStore"]; 

     NSString *shippedDB = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"persistentStore"]; 

     NSLog(@"%d",[fileManager fileExistsAtPath:shippedDB]); 

     [fileManager copyItemAtPath:shippedDB toPath:DB error:&error]; 

     NSLog(@"Copy error %@",error); 

    } 

    NSLog(@"== My-Default-Document-As-Database OK DANS DOCUMENTS =="); 

    NSURL *myDbUrl = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 

    myDbUrl = [myDbUrl URLByAppendingPathComponent:@"My-Default-Document-As-Database/"]; 

    self.document = [[UIManagedDocument alloc] initWithFileURL:myDbUrl]; 

    NSLog(@"== initWithFileUrl =="); 

      // Set our document up for automatic migrations 
      NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
            [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
            [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 
      self.document.persistentStoreOptions = options; 


      // Register for notifications 
      [[NSNotificationCenter defaultCenter] addObserver:self 
                selector:@selector(objectsDidChange:) 
                 name:NSManagedObjectContextObjectsDidChangeNotification 
                 object:self.document.managedObjectContext]; 

      [[NSNotificationCenter defaultCenter] addObserver:self 
                selector:@selector(contextDidSave:) 
                 name:NSManagedObjectContextDidSaveNotification 
                 object:self.document.managedObjectContext]; 
} 
return self; 
} 

Tylko „modyfikacje” zrobiłem na kodzie performWithDocument dostarczonych przez pana Driscoll niektóre NSLog aby zobaczyć co się hapening (stan doc iść od 1 do 5 na każdy najpierw otwórz spróbuj, a następnie przykleić do 5 ...)

- (void)performWithDocument:(OnDocumentReady)onDocumentReady 
{ 
NSLog(@"passage par performWithDoc"); 

void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) { 
    NSLog(@"FilePath Apres = %@",[self.document.fileURL path]); 
    NSLog(@"STATE === %d", self.document.documentState); 
    onDocumentReady(self.document); 
}; 

NSLog(@"FilePath Avant = %@",[self.document.fileURL path]); 
NSLog(@"STATE === %d", self.document.documentState); 

if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) { 
    [self.document saveToURL:self.document.fileURL 
      forSaveOperation:UIDocumentSaveForCreating 
      completionHandler:OnDocumentDidLoad]; 
    NSLog(@"performWithDoc > fileexistAtPath nope => saveToURLForCreating"); 
    NSLog(@"STATE === %d", self.document.documentState); 
} else if (self.document.documentState == UIDocumentStateClosed) { 
    [self.document openWithCompletionHandler:OnDocumentDidLoad]; 
    NSLog(@"performWithDoc > UIDocStateClosed => openWithCompletionHandler"); 
    NSLog(@"STATE === %d", self.document.documentState); 
} else if (self.document.documentState == UIDocumentStateNormal) { 
    OnDocumentDidLoad(YES); 
    NSLog(@"performWithDoc > docState = normal => docdidLoad(YES)"); 
} 
NSLog(@"STATE === %d", self.document.documentState); 
} 

Odpowiedz

2

Dzięki kompadrowi, oto odpowiedź ... jeśli ktoś go szuka:

Chodziło o opcje !!

Dodaj NSIgnorePersistentStoreVersioningOption do opcji pesistenStore w init.

Odnośnie poprzedniego kodu, trzeba mieć coś takiego:

// Set our document up for automatic migrations 
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
    [NSNumber numberWithBool:YES], NSIgnorePersistentStoreVersioningOption, 
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 
self.document.persistentStoreOptions = options; 
+0

dla iOS te opcje nie są obecne. Kod w pytaniach działał bez tych opcji. – vaichidrewar

+0

@vaichidrewar dziwne, nie dla mnie w rzeczywistości. Muszę dodać tę opcję NSIgnorePersistentStoreVersioningOption, aby móc korzystać z zmigrowanego magazynu persistentStore (bez opcji, aplikacja zawsze odmawia otwarcia sklepu).Opcje są szczegółowo opisane w dokumencie iOS: http://developer.apple.com/library/ios/#Documentation/Cocoa/Reference/CoreDataFramework/Classes/NSPersistentStoreCoordinator_Class/NSPersistentStoreCoordinator.html – macbeb

+0

Myślę, że chciałem powiedzieć, że nie są potrzebne do iphone ios. Xcode nie rozpoznaje tych opcji podczas rozwijania aplikacji na telefon iPhone. Ale te powinny być ważne dla Mac app – vaichidrewar