8

我很想知道在 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 为我做了多少,我应该确保我在做什么。我还没有找到太多关于这方面的文档,并且想清楚地说明这一点。

4

2 回答 2

11

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

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

当 时YES,上下文通过NSManagedObjectContextcategory 方法递归地一直保存到持久存储中saveToPersistentStore(请参阅http://restkit.org/api/0.20.0/Categories/NSManagedObjectContext+RKAdditions.html)。

当 时NO,上下文通过原始[NSManagedObjectContext save:] 消息保存,该消息将更改“推送”回父上下文。在您将它们保存回来之前,它们将保持在该上下文的本地。请记住,托管对象上下文父/子层次结构只要您在应用程序中创建即可。

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

于 2012-12-06T21:18:16.157 回答
3

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

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

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

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

至于你的第二个问题,如果一切都很好地映射/设置,RestKit 应该在你的 api 调用成功后管理保存/更新你的核心数据堆栈。

来自 RK 的创造者布莱克:

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

于 2012-12-06T21:06:20.337 回答