RestKit 0.20 - 创建新NSManagedObject的首选方法是什么?

时间:2012-12-06 20:54:14

标签: restkit restkit-0.20

我很想知道在RestKit 0.20中创建一个新的NSManagedObject的最佳方法是什么?目前我的代码看起来像这样:

#pragma mark - navigation buttons

- (void)createButtonDidTouch
{
    // create new album object    
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    NSManagedObjectContext *parentContext = RKObjectManager.sharedManager.managedObjectStore.mainQueueManagedObjectContext;
    context.parentContext = parentContext;
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:parentContext];
    Album *newAlbum = [[Album alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];

    // pass object to create view to manipulate
    AlbumCreateViewController *createViewController = [[AlbumCreateViewController alloc] initWithData:newAlbum];
    createViewController.delegate = self;
    createViewController.managedObjectContext = context;

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:createViewController];
    navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

    [self presentViewController:navController animated:YES completion:nil];
}

#pragma mark - create view controller delegate

- (void)createViewControllerDidSave:(NSManagedObject *)data
{
    // dismiss the create view controller and POST

    // FIXME: add restkit code to save the object
    NSLog(@"save the object...");

    NSDictionary *userInfo = [KeychainUtility load:@"userInfo"];
    NSString *path = [NSString stringWithFormat:@"/albums/add/%@/%@", userInfo[@"userID"], userInfo[@"apiKey"]];

    [RKObjectManager.sharedManager postObject:data path:path parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        operation.targetObject = data;
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        NSLog(@"create album error: %@", error);
    }];

    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)createViewControllerDidCancel:(NSManagedObject *)data
{
    // dismiss the create view controller

    NSLog(@"delete the object...");
    // FIXME: add restkit code to delete the object

    [self dismissViewControllerAnimated:YES completion:nil];
}

我也很想知道保存/删除此对象的责任。如果我通过RestKit POST到服务器是否保存了托管对象上下文?

如果我决定取消此创建过程该怎么办 - 删除此对象的首选方法是什么?

基本上RestKit为我做了多少,我应该确定我在做什么。我没有找到很多关于此的文档,并希望明确它。

2 个答案:

答案 0 :(得分:11)

为给定对象初始化RKManagedObjectRequestOperation时,RestKit将获取该对象的永久对象ID,然后创建子上下文,其父上下文是插入对象的上下文。然后,该操作执行HTTP请求以完成并获得响应。

如果响应成功并且响应的映射成功(请注意映射发生在此私有子上下文中),则保存私有子上下文。调用的保存类型由savesToPersistentStore属性的值确定(请参阅http://restkit.org/api/0.20.0/Classes/RKManagedObjectRequestOperation.html#//api/name/savesToPersistentStore)。

YES时,通过NSManagedObjectContext类别方法saveToPersistentStore以递归方式保存上下文一直回到持久性商店(参见http://restkit.org/api/0.20.0/Categories/NSManagedObjectContext+RKAdditions.html)。

NO时,通过香草[NSManagedObjectContext save:]消息保存上下文,该消息会推送'更改回父上下文。它们将保留在该环境的本地,直到您将它们保存回来。请记住,托管对象上下文父/子层次结构可以在应用程序中创建。

如果HTTP请求失败或映射过程中出现错误,则不会保存私有上下文,并且操作被视为失败。这意味着没有更改保存回原始MOC,使对象图形与操作开始之前一样(除了正在发送的对象,如果是临时的,现在具有永久对象ID但仍未保存)。

答案 1 :(得分:3)

你这样做的方式应该有效(每次你的VC都要调用MOC),但不是“推荐”。

Apple建议,就像任何Core Data应用程序一样,是“传递接力棒”的风格。

  

嵌套上下文比以往任何时候都更重要   “传递接力棒”访问上下文的方法(通过传递上下文   从一个视图控制器到下一个视图控制器而不是检索它   直接来自应用程序代理。

见这里: http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/_index.html

关于你的第二个问题,如果所有内容都经过良好的映射/设置,RestKit应该在api调用成功后管理保存/更新你的核心数据堆栈。

来自Blake RK创作者:

  

如果你POST或PUT一个Core Data对象,RK会获得一个永久对象   它的ID然后创建一个辅助管理对象上下文,触发   请求,并映射响应(如果可能)。如果回应和   映射成功后,它会将其保存回父级   上下文或一直回到持久存储(即进入SQLite)   基于savesToPersistentStore的值。