0

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

- (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];
}
4

1 回答 1

0

好吧,这就是我最终做的事情——无论好坏:

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

     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]);
    }
    
于 2013-12-11T21:22:05.693 回答