2013-05-07 59 views
1

我有一個NSPersistentDocument與給定的核心數據模型等如何從NSPersistentDocument中的核心數據預加載數據?

我有一個文件,這個文件創建的,比方說,它的preload.xml。它「包含」幾個NSManagedObject s。

我想在我的所有新文檔中加載這些對象,這樣當我創建一個新文檔時,新文檔會自動「擁有」preload.xml中的「生存」對象。到目前爲止,這裏是我做過什麼:

  • 我在我的項目複製preload.xml

  • initWithType:error:法(創建一個新文檔時調用的方法),有下面的代碼:

    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] 
                  pathForResource:@"preload" 
                  ofType:@"xml"]]; 
    NSError* err = nil; 
    
    [self readFromURL:preloadURL 
          ofType:@"xml" 
          error:&err] ; 
    

這不工作,因爲,當我嘗試之後救我文件,比方說myNewDoc.xml,這個文件是空的,但我所有的新數據保存到preload.xml

我想知道是否需要創建新的storecontextstoreCoordinator或其他東西。我從來沒有處理過這種物體,因爲我總是使用NSPersistentDocument

+0

你覆蓋'readFromURL克隆技術的幫助:ofType :錯誤:'?如果是這樣,你的版本是什麼樣子? – 2013-05-07 19:43:44

+0

是的,我重寫'readFromURL',但它不起作用。我做了其他的事情,因爲:創建一個新的'store'(與我的preload.xml關聯),一個新的'storeCoord'和一個新的'MOC'。然後,我在兩個MOC之間克隆了我的對象,這並不是很好......但它似乎工作。 – Colas 2013-05-07 20:00:59

+0

好吧,它聽起來像原來的問題是與你的'readFromURL:ofType:error:'代碼有關的,因爲你沒有包括它很難說出什麼可能是錯的。 – 2013-05-07 20:03:26

回答

1

獲取已保存的對象:

NSPersistentStoreCoordinator * newPersStoreCoord ; 
    newPersStoreCoord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:theDoc.managedObjectModel] ; 

    NSString * path = [[NSBundle mainBundle] pathForResource:@"preload" 
                 ofType:@"xml"]; 
    NSURL *preloadURL = [NSURL fileURLWithPath:path]; 



    [newPersStoreCoord addPersistentStoreWithType:NSBinaryStoreType 
            configuration:nil 
               URL:preloadURL 
              options:nil 
              error:NULL] ; 

    NSManagedObjectContext * auxMOC = [[NSManagedObjectContext alloc] init] ; 
    [auxMOC setPersistentStoreCoordinator:newPersStoreCoord] ; 

將它們複製到 「活」 MOC

[self loadPreloadedDataFromTheMOC:auxMOC 
          toTheMOC:theDoc.managedObjectContext 
          forTheDoc:theDoc] ; 

- (NSManagedObject *)cloneInContext:(NSManagedObjectContext *)context 
        withCopiedCache:(NSMutableDictionary *)alreadyCopied 
        exludeEntities:(NSArray *)namesOfEntitiesToExclude 
        excludeAttributes:(NSArray *)namesOfAttributesToExclude 
{ 
    NSString *entityName = [[self entity] name]; 

    if ([namesOfEntitiesToExclude containsObject:entityName]) 
    { 
     return nil; 
    } 

    NSManagedObject *cloned = [alreadyCopied objectForKey:[self objectID]]; 
    if (cloned != nil) 
    { 
     return cloned; 
    } 


    //create new object in data store 
    cloned = [NSEntityDescription insertNewObjectForEntityForName:entityName 
              inManagedObjectContext:context]; 
    [alreadyCopied setObject:cloned 
         forKey:[self objectID]]; 

    //loop through all attributes and assign then to the clone 
    NSDictionary *attributes = [[NSEntityDescription entityForName:entityName 
              inManagedObjectContext:context] attributesByName]; 


    for (NSString *attr in attributes) 
    { 
     if (![namesOfAttributesToExclude containsObject:attr]) 
     { 
      [cloned setValue:[self valueForKey:attr] forKey:attr]; 
     } 
    } 

    //Loop through all relationships, and clone them. 
    NSDictionary *relationships = [[NSEntityDescription entityForName:entityName 
               inManagedObjectContext:context] relationshipsByName]; 



    for (NSString *relName in [relationships allKeys]) 
    { 
     NSRelationshipDescription *rel = [relationships objectForKey:relName]; 

     NSString *keyName = rel.name; 

     if ([rel isToMany]) 
     { 
      id sourceSet ; 
      id clonedSet ; 

      /* 
      On gère selon que la relation est ordonnée ou non 
      */ 
      if (![rel isOrdered]) 
      { 
       //get a set of all objects in the relationship 
       sourceSet = [self mutableSetValueForKey:keyName]; 
       clonedSet = [cloned mutableSetValueForKey:keyName]; 
      } 
      else 
      { 
       sourceSet = [self mutableOrderedSetValueForKey:keyName]; 
       clonedSet = [cloned mutableOrderedSetValueForKey:keyName]; 
      } 

      NSEnumerator *e = [sourceSet objectEnumerator]; 
      NSManagedObject *relatedObject; 

      while (relatedObject = [e nextObject]) 
      { 
       //Clone it, and add clone to set 
       NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context 
                    withCopiedCache:alreadyCopied 
                     exludeEntities:namesOfEntitiesToExclude 
                    excludeAttributes:namesOfAttributesToExclude]; 
       if (clonedRelatedObject) 
       { 
        [clonedSet addObject:clonedRelatedObject]; 
       } 
      } 
     } 
     else 
     { 
      NSManagedObject *relatedObject = [self valueForKey:keyName]; 
      if (relatedObject != nil) 
      { 
       NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context 
                    withCopiedCache:alreadyCopied 
                     exludeEntities:namesOfEntitiesToExclude 
                    excludeAttributes:namesOfAttributesToExclude]; 
       if (clonedRelatedObject) 
       { 
        [cloned setValue:clonedRelatedObject forKey:keyName]; 
       } 
      } 
     } 
    } 

    return cloned; 
}