2011-12-13 46 views
0

我正在使用NSXMLParser和核心數據解析Feed並在我的iPhone應用程序中使用核心數據添加/更新實體。使用NSXMLParser和核心數據更新實體的功能

的問題是,飼料中含有新的和更新數據,所以一旦我解析飼料會發生以下情況:

  1. 創建一個新的實體
  2. 使用的NSXMLParser
  3. 在didEndElement填充實體屬性,使用與我們解析的實體相同的myEntityId獲取系統中已有的實體。
  4. 如果有超過1個實體,那麼在饋送傳遞給我們新數據時刪除舊的。
  5. 保存實體

我的問題是,它似乎是一個大量的工作,以節省更新信息,並且代碼也總是創建一個新的記錄,而不是僅僅更新當前記錄。

無論如何,這個過程可以變得更簡單,避免需要創建一個新的實體並刪除舊的更新?

我的縮寫代碼如下:

DidStartElement

- (void)parser:(NSXMLParser *)parser didStartElement... 
{ 
    if ([elementName isEqualToString:@"AnEntity"]) 
    { 
    NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:_context]; 
    self.currentEntityObject = newEntity; 
    } else 
    { 
    if ([elementName isEqualToString:@"Title"] || [elementName isEqualToString:@"MyEntityId"]) 
    { 
     self.currentProperty = [NSMutableString string]; 
    } 
    } 
} 

DidEndElement

- (void)parser:(NSXMLParser *)parser didEndElement... 
{ 
    if (self.currentEntityObject) 
    { 
    if ([elementName isEqualToString:@"Title"]) 
    { 
     [self.currentEntityObject setValue:self.currentProperty forKey:@"title"]; 

    } else if ([elementName isEqualToString:@"MyEntityId"]) 
    { 
     [self.currentEntityObject setValue:self.currentProperty forKey:@"myEntityId"]; 

    } else if ([elementName isEqualToString:@"AnEntity"]) 
    { 
     [self.currentEntityObject setValue:[NSDate date] forKey:@"lastUpdated"]; 

     NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:_context]; 
     NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
     [request setEntity:entity]; 

     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(myEntityId = %@)", [self.currentEntityObject valueForKey:@"myEntityId"]]; 
     [request setPredicate:predicate]; 

     NSError *error = nil; 
     NSArray *array = [_context executeFetchRequest:request error:&error]; 

     int countOfEntityId = array.count; 

     if (array != nil && countOfEntityId > 1) 
     { 
     // This is an update so remove old versions 
     for(int i=0; i < countOfEntityId; i++) 
     { 
      if(self.currentEntityObject != [array objectAtIndex:i]) 
      { 
      [_context deleteObject:[array objectAtIndex:i]]; 
      } 
     } 
     } 

     error = nil; 
     [_context save:&error]; 

     self.currentEntityObject = nil; 
    } 
    } 
} 

FoundCharacters

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    if (self.currentProperty) 
    { 
     [currentProperty appendString:string]; 
    } 
} 

我的問題是,它好像很多Ø f工作來保存更新信息,並且它總是創建新記錄而不是僅更新當前記錄。

無論如何,這個過程可以變得更簡單,避免需要創建一個新的實體並刪除舊的更新?

任何建議將是偉大的。

感謝 豐富

回答

1

我意識到這是一個老的文章,但我反正回答。

你一定要看看Saul Mora的MagicRecord。他讓它在任何項目中都很容易使用,可以自動與ARC /非ARC進行協作,並且CoreData的設置是一次性的。

首先我會告訴你我是如何解析和更新的。

- (void)setUpBeforeParsing 
{ 
    self.currentAttributes = [NSMutableDictionary dictionary]; 

    self.currentParsedCharacterData = [NSMutableString string]; 

    self.currentParsedBatch = [NSMutableArray array]; 

    self.attributesDictionary = myManagedObjectObject.entity.attributesByName; 
} 

- (void)parser:(NSXMLParser *)parser didStartElement... 
{ 
    for (NSString *attribute in self.attributesDictionary) 
    { 
     if ([elementName isEqualToString:attribute]) 
     { 
      accumulatingParsedCharacterData = YES; 

      [self.currentParsedCharacterData setString:@""]; 
     } 
    } 
} 


- (void)parser:(NSXMLParser *)parser didEndElement... 
{ 

    if ([elementName isEqualToString:@"myIdentifierThatObjectIsDone"]) 
    { 
     [self.currentParsedBatch addObject:[self.currentAttributes copy]]; 
     [self.currentAttributes removeAllObjects]; 
     accumulatingParsedCharacterData = NO; 
    } 
    for (NSString *attribute in self.attributesDictionary) 
    { 
     if ([elementName isEqualToString:attribute]) 
     { 
      accumulatingParsedCharacterData = NO; 

      [self.currentAttributes setObject:[self.currentParsedCharacterData copy] forKey:attribute]; 
     } 
    } 
} 


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    if (self.accumulatingParsedCharacterData) [self.currentParsedCharacterData appendString:string]; 
} 

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{ 
    [MyCoreDataClass MR_importFromArray:self.currentParsedBatch]; 
} 

真的最主要採取從這個就是你可以構建攜帶要轉移到你的管理對象值的字典的數組。一個名叫湯姆哈林頓的人在cimgf.com上寫了一個演示,關於命名你的對象的屬性和返回的xml或json一樣,然後你可以遍歷你的屬性,直到它匹配返回的xml元素。這裏的美妙之處在於,您希望將更多返回的xml保存到對象中,只需將屬性添加到對象中,解析器就會自動同步它。

在解析結束時,您會注意到一個名爲的方法,它來自於MagicalRecord框架。只要您在數據模型的用戶信息部分設置'relatedByAttribute',它就會自動將字典同步到您的託管對象。因此,如果你的對象有一個唯一標識屬性叫做「MyEntityId」,那麼在你的實體集的'relatedByAttribute' - 'MyEntityId'和MagicalRecord的用戶信息字典中負責它。

讓我知道你是否需要任何澄清。