2011-12-13 145 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的用户信息字典中负责它。

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