簡體   English   中英

將現有Core Data遷移到iCloud

[英]Migrating existing Core Data to iCloud

我有一個簡單的應用程序,它是一個UITableView ,由用戶在不同的視圖中填充一些UITextFields來填充。 該信息被保存到CoreDataUITableView得到使用更新NSFetchedResultsController

我現在正在將iCloud同步到我的環境中。 參考之前提出的問題: 現有的核心數據數據庫沒有上傳到iCloud當我在我的應用程序上啟用iCloud時 ,我仍然遇到問題,但是用我的新代碼更新問題太麻煩了。 我指的是WWDC 2013 CoreData Sessions,以及這個 因為我的應用只是iOS 7。 我是iCloud開發的新手,也是一名中級程序員。

當我從App Store(非iCloud)版本更新到開發(iCloud)版本時,我將現有數據遷移到iCloud時遇到很大困難。 新數據完美同步。

據我所知,我需要在沒有iCloud的情況下將我現有的商店遷移到iCloud,但這對我來說並不合適。

這里有一些代碼來說明我正在做的事情:

更新

我已經完成並考慮了這一點並刪除了多余的代碼。

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

     NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Planner.sqlite"];
     NSFileManager *fm = [NSFileManager defaultManager];
     NSURL *url = [fm URLForUbiquityContainerIdentifier:nil];
     NSError *error = nil;
     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

     if (url)
     {
         NSLog(@"iCloud is enabled");
         NSDictionary *options = @{
                                   NSMigratePersistentStoresAutomaticallyOption : @YES,
                                   NSInferMappingModelAutomaticallyOption : @YES,
                                   };

         NSPersistentStore *localStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

         [_persistentStoreCoordinator migratePersistentStore:localStore toURL:[self iCloudURL] options:[self iCloudStoreOptions] withType:NSSQLiteStoreType error:&error];

     }
     else
     {
         NSLog(@"iCloud is not enabled");
         NSDictionary *options = @{
                                   NSMigratePersistentStoresAutomaticallyOption : @YES,
                                   NSInferMappingModelAutomaticallyOption : @YES
                                   };

         if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self iCloudURL] options:options error:&error])
         {
             NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
             abort();

         }

     }

     dispatch_async(dispatch_get_main_queue(), ^{

    [[NSNotificationCenter defaultCenter] postNotificationName:@"Reload" object:self userInfo:nil];
});

     return _persistentStoreCoordinator;
}

我不再調用migrateLocalStoreToiCloud方法,但它在這里供參考:

/*-(void)migrateLocalStoreToiCloud
{
    //assuming you only have one store.
    NSPersistentStore *store = [[_persistentStoreCoordinator persistentStores] firstObject];
    NSPersistentStore *newStore = [_persistentStoreCoordinator migratePersistentStore:store
                                                                                toURL:[self iCloudURL]
                                                                              options:[self iCloudStoreOptions]
                                                                             withType:NSSQLiteStoreType
                                                                                error:nil];
    [self reloadStore:newStore];
}

* /

storeURLstoreOptionsiCloudURLiCloudStoreOptions代碼是:

- (NSURL *)iCloudURL
{
    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *url = [fm URLForUbiquityContainerIdentifier:nil];
     if (url) {
     NSLog(@"iCloud access at %@", url);
     } else {
     NSLog(@"No iCloud access");
     }
    return url;
}

-(NSURL *)storeURL{
    return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Planner.sqlite"];
}


-(NSDictionary *)storeOptions{
    NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
    return options;
}

-(NSDictionary *)iCloudStoreOptions{
    NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
    [options setObject:@"PlannerStore" forKey:NSPersistentStoreUbiquitousContentNameKey];
    return options;
}

問題

當我完全按原樣運行此代碼時,我沒有在使用Local Storage : 1的控制台中顯示Local Storage : 10 ,盡管數據在那里。

如果我更改persistentStoreCoordinator ,它首先添加persistentStore以使用[self iCloudStoreOptions]作為選項,則顯示Using Local Storage 10 ,但數據不在設備上。

我正在遵循這里的指導,我嘗試了多種代碼,包括不在reloadStore方法中刪除任何persistentStore,但我完全卡住了。

我已經閱讀了這么多帖子,但似乎我找不到將數據從非iCloud版本遷移到iCloud版本的人,並且我找到的示例中沒有代碼。

我已經研究了這個 ,雖然它是一個很棒的代碼集,但我已經下載了代碼並遵循了那些不刪除任何persistentStore的指南,但它仍然不適用於我。 我無法想象我想要實現的目標非常復雜。 我只需要獲取現有的非iCloud數據並將其遷移到iCloud。

更新

閱讀Apple的指南: https//developer.apple.com/LIBRARY/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html#//apple_ref/doc/uid/TP40013491-CH3-SW2我可以看到我的migrateLocaltoiCloud方法目前在刪除persistentStore等方面是錯誤的,但我無法弄清楚如何修復它。 如果我從persistentStoreCoordinator調用它,它會以某種方式干擾DidChangeNotification嗎?

我真的堅持這一點,我希望任何指導正確的方向

我在這里提出了一個問題的答案,因為它比更新問題更清楚,經過大量的調試后,我在某種程度上有了這個工作。

通過調試addPersistentStoremigratePersistentStore代碼行,我想出了:

 NSPersistentStore *localStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

 NSLog(@"The localStore is %@", localStore);

 NSPersistentStore *migratedStore = [_persistentStoreCoordinator migratePersistentStore:localStore toURL:[self iCloudURL] options:[self iCloudStoreOptions] withType:NSSQLiteStoreType error:&error];

 NSLog(@"The migrationStore is %@", migratedStore); 

The NSLog value of localStore is: The localStore is <NSSQLCore: 0x13451b100> (URL: file:///var/mobile/Applications/DDB71522-C61D-41FC-97C7-ED915D6C46A4/Documents/Planner.sqlite)

The NSLog value of migratedStore is: (null)

通過調試,我可以看到基本相同的東西,migrateStore始終為null。

我稍微更改了代碼:

 NSPersistentStore *migratedStore = [_persistentStoreCoordinator migratePersistentStore:localStore toURL:storeURL options:[self iCloudStoreOptions] withType:NSSQLiteStoreType error:&error];

要使URL成為storeURL,突然之間,一切都開始工作了,其中storeURL:

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

我的產出是:

The localStore is <NSSQLCore: 0x14ee09b50> (URL: file:///var/mobile/Applications/CC0F7DA0-251F-46D6-8E43-39D63062AED2/Documents/Planner.sqlite)
[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](771): CoreData: Ubiquity:  mobile~5BD59259-7758-42FB-986F-DDD173F75ED3:EnStor
The migrationStore is <NSSQLCore: 0x157e260b0> (URL: file:///var/mobile/Applications/A08D183D-ECD4-4E72-BA64-D21727DE7A3E/Documents/CoreDataUbiquitySupport/mobile~CB6C3699-8BF1-47DB-9786-14BCE1CD570A/EnStor/771D2B0B-870A-428E-A9A8-5DAE1295AF53/store/Planner.sqlite)

使用本地存儲從1到0,應用程序的App Store版本中的數據繼續通過遷移到新版本。 這是我在升級后第一次運行應用程序時的輸出。

這是個好消息。

隨后我運行應用程序時,數據繼續遷移,因此我最終會得到重復的結果。

問題還在於,在添加新設備時,它不會將信息下載到新設備。

我不太明白為什么使用storeURL作為migratePersistentStore的url工作?

我也不希望每個新設備基本上添加一個新的持久性存儲(如果已存在)並且我不知道如何解決這個問題並且我也不希望一次又一次地進行遷移。 它應該只發生一次。

我到了那里,但還有很多工作要做!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM