将允许外部存储的核心数据模型移动到UIManagedDocument中

时间:2013-10-31 15:00:39

标签: ios core-data storage external uimanageddocument

将允许外部存储转换为UIManagedDocument的核心数据模型的正确方法是什么?我有一个核心数据存储,我试图进入UIManagedDocument。我的用户拥有大量数据。其中一些是2 - 3分钟的音频剪辑。我是子类化UIManaged文档并重写configurePersistentStoreCoordinatorForURL。然后将文件复制到UIManagedDocument包中。对于外部存储的音频文件,这似乎都很好用。在我的核心数据模型中,我的音频文件设置为允许外部存储。这些文件在移动后不再连接,当我尝试在移动后在应用程序中播放它们时,我收到音频会话错误。感谢您提供有关该主题的任何帮助。这是我用来覆盖UIMD的代码......

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)storeURL
                                       ofType:(NSString *)fileType
                           modelConfiguration:(NSString *)configuration
                                 storeOptions:(NSDictionary *)storeOptions
                                        error:(NSError *__autoreleasing *)error{
  [self printFileDir];
  // If legacy store exists, create a UIManaged Document and store it there
  NSURL *docsDir = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
  NSURL *legacyStoreURL = [docsDir URLByAppendingPathComponent:@"RRLevelBook.sqlite"];

  NSFileManager* fileManager = [NSFileManager defaultManager];
  if ([fileManager fileExistsAtPath:legacyStoreURL.path])
  {
      NSLog(@"Old db exists");

      //swap files
      NSURL *storeURLshm = [NSURL URLWithString:[[storeURL absoluteString] stringByAppendingString:@"-shm"]];
      NSURL *storeURLwal = [NSURL URLWithString:[[storeURL absoluteString] stringByAppendingString:@"-wal"]];
      NSURL *supportFiles = [[storeURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:@".persistenStore_SUPPORT"];
      NSURL *legacyStoreURLshm = [NSURL URLWithString:[[legacyStoreURL absoluteString] stringByAppendingString:@"-shm"]];
      NSURL *legacyStoreURLwal = [NSURL URLWithString:[[legacyStoreURL absoluteString] stringByAppendingString:@"-wal"]];
      NSURL *legacySupportFiles = [[legacyStoreURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:@".RRLevelBook_SUPPORT"];

      NSError* thisError = nil;

      //swap the sqlite file
      [fileManager replaceItemAtURL:storeURL
                    withItemAtURL:legacyStoreURL
                   backupItemName:nil
                          options:NSFileManagerItemReplacementUsingNewMetadataOnly
                 resultingItemURL:nil
                            error:&thisError];
      //swap the -shm file
      [fileManager replaceItemAtURL:storeURLshm
                    withItemAtURL:legacyStoreURLshm
                   backupItemName:nil
                          options:NSFileManagerItemReplacementUsingNewMetadataOnly
                 resultingItemURL:nil
                            error:&thisError];

      //swap the -wal file
      [fileManager replaceItemAtURL:storeURLwal
                    withItemAtURL:legacyStoreURLwal
                   backupItemName:nil
                          options:NSFileManagerItemReplacementUsingNewMetadataOnly
                 resultingItemURL:nil
                            error:&thisError];
      //Move in the Support files
      [fileManager moveItemAtURL:legacySupportFiles toURL:supportFiles error:nil];

      //delete old files that have been swapped
      [fileManager removeItemAtURL:legacyStoreURL error:nil];
      [fileManager removeItemAtURL:legacyStoreURLwal error:nil];
      [fileManager removeItemAtURL:legacyStoreURLshm error:nil];
      [fileManager removeItemAtURL:legacySupportFiles error:nil];

      NSLog(@"%@",[thisError localizedDescription]);
  }

  [self printFileDir];
  return [super configurePersistentStoreCoordinatorForURL:storeURL ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error];
}

1 个答案:

答案 0 :(得分:0)

嗯,这就是我最终做的 - 无论好坏:

  1. 打开新的UIManagedDocument。
  2. 打开旧版核心数据模型。
  3. 将每个音频文件(NSData)从Legacy CoreData Context复制到UIManagedDocument Context。
  4. 根据Legacy CoreData Context重新连接所有关系。

     NSManagedObjectContext *legacyMOC = [[NSManagedObjectContext alloc]init];
     [legacyMOC setPersistentStoreCoordinator:psc];
    
    
    //fetch all audio recordings from legacyStore
    NSArray *legacyRecordingArray = [self fetchAudioRecordingsfrom:legacyMOC];
    
    //fetch all audio recordings form UIMDStore
    NSArray *uimdRecordingArray = [self fetchAudioRecordingsfrom:self.managedObjectContext];
    
    //for each audio recording, copy the audio object from legacy and save it to UIMDStore
    for (int i = 0; i < legacyRecordingArray.count; i++) {
    
       //save audio to core data
       RunningRecord *legacyRR = (RunningRecord *)legacyRecordingArray[i];
       RunningRecord *uimdRR = (RunningRecord *)uimdRecordingArray[i];
       uimdRR.audioData =  [NSData dataWithData:legacyRR.audio.file];
       uimdRR.audio.file = nil;
    }
    
    
    if (![self.managedObjectContext save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }