使用MagicalRecord和MMRecord在Core Data中复制NSManagedObjects

时间:2014-07-17 09:00:12

标签: afnetworking magicalrecord mmrecord

2014年3月21日更新:我找到了解决此处所述问题的方法。我创建了一个名为downloadContext的独立NSManagedObjectContext。下载的序列化对象放在单独的上下文中。然后我遍历响应数组并检查对象是否已经存在于MR_defaultContext中(使用主键)。 如果是,我使用相同的主键更新下载对象的属性。不可能简单地复制整个对象,从而覆盖现有对象的所有属性(因为更新的对象和旧对象在不同的​​上下文中)。相反,我将下载对象的所有属性复制到NSDictionary(dictionaryWithValuesForKeys)中,然后使用setValuesForKeysWithDictionary覆盖旧对象的属性。必须对子对象进行相同的操作。 如果对象是新的,我创建一个新对象并以相同的方式复制属性。我需要检查这个解决方案是否足够有效,或者如果有许多对象要下载(第一次同步),它将占用太多内存。另一种方法是创建我自己的序列化器,该序列化器根据主键决定是更新现有对象还是创建新对象。


对于这个问题,请注意我已经看到了对relatedByAttribute键设置的讨论。在这种情况下它没有帮助,因为这可能只避免重复的子关系对象(我没有检查是否有重复)。这是关于父对象重复。

在我的项目中,我将AFNetworking,MMRecord和MagicalRecord一起用作依赖项。情况如下:

我从AFMMRecordResponseSerializer类创建一个响应序列化器,我只是将其设置为AFHTTPSessionManager的子类对象。使用此会话管理器,我向服务器发送GET请求。响应对象已经包含序列化的NSManagedObjects(它们实际上是MMRecord的子类)。我已将MMRecordEntityPrimaryAttributeKey设置为每个NSManagedObject的预期主键。我认为问题在于MagicalRecords,因为它只是忽略了MMrecord的主要属性键设置。

在持久存储仍为空的初始GET请求之后,没有修改/创建日期谓词。如果已存在持久对象,则GET请求包含一个谓词,该谓词仅从服务器检索最后一个mod日期之后的对象。因此更新的对象是持久的,但旧的对象不会被覆盖。当我在表视图中显示对象的标题时,我可以看到显示对象的旧版本和更新版本。要点:表视图仅从核心数据填充,而不是直接从responseObject(包含序列化对象)填充。 以下是最重要的代码。 感谢您提供正确方向的任何提示 多米尼克

-(void) fetchNotesFromServer
 {
    NSLog(@"fetchNotesFromServer called");
    self.sessionManager.responseSerializer = [self getSerializerForEntityName:@"NAS_Notes" AndEndPointPathComponent:@"DBFetchNotes.php?"];
[self.sessionManager GET:[self getFetchNotesExtension] parameters:nil   
     success:^(NSURLSessionDataTask *task, id responseObject) 
    {  
       if (responseObject )
         {
           NSLog(@"fetch all notes response: %@", responseObject);
           self.latestNotes = (NSMutableArray *)responseObject;
               if ([self.latestNotes count] > 0) 
                    {
                        [self saveDownloadedNotesInContext:[NSManagedObjectContext MR_defaultContext]];
                    }              
           }
    } failure:^(NSURLSessionDataTask *task, NSError *error) 
        {    
            NSLog(@"NSerror %@", error); 
        }];}

-(void) saveDownloadedNotesInContext:(NSManagedObjectContext *)context{
    [context MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
    if (success) {
                [self.delegate didFinishNotesSync:self];
               }
    else if (error) {
        NSLog(@"error saving to persistent store %@", error);
              }  
    }];

}

0 个答案:

没有答案