3

在过去的几周里,我正在学习 Restkit (v0.10.0) 和核心数据,这些出色的工具提供了无限的可能性。问题是我对如何在这里看到更大的图景有点不知所措。而且由于 Restkit 的更新速度非常快,大多数教程/演示代码已经过时并且不再正常工作。

我已经设法让我的 tableview 充满了远程服务器上我的 json 中的数据。我还研究了如何使远程数据与缓存相结合现在工作,但我正在努力解决 NSManagedObjectContext/NSEntityDescription(核心数据)以及在使用 POST 命令时它如何与 Restkit 一起工作。

如果我理解正确,记录是在 Core Data 中创建的(在注释行 // Create a new instance 之后),然后该数据用于创建 POST 请求,以便将记录发布到服务器。

此代码用于在服务器上创建一条新记录,但是当代码执行时(我看到在我的服务器上创建了一条记录)但我的 tableview 没有相应更新,table view 没有更新,因此新记录是重新启动应用程序时首次可见。从服务器手动刷新数据也无济于事。

希望有人可以给我一些指示,或者可能是一个包含 Restkit/核心数据和 POST 的教程。谢谢!

- (void)createGoalWithName:(NSString *)name andDescription:(NSString *)goalDescription
{
    Goal* goal = [Goal object];
    goal.identifier = 0;
    goal.name = name;
    goal.goalDescription = goalDescription;

    // Create a new instance of the entity managed by the fetched results controller.
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
    [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

    [self saveContext];

    [[RKObjectManager sharedManager].router routeClass:[Goal class] toResourcePath:@"/api/goals" forMethod:RKRequestMethodPOST];

    [[RKObjectManager sharedManager] postObject:goal delegate:self];

    [self.tableView reloadData];
}

- (void)saveContext {
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSError *error = nil;
    if (![context save:&error]) {
    /*
     Replace this implementation with code to handle the error appropriately.

     abort() causes the application to generate a crash log and terminate. 

     You should not use this function in a shipping application, 
     although it may be useful during development. 

     If it is not possible to recover from the error, 
     display an alert panel that instructs the user to quit the application by pressing the Home button.
     */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
4

3 回答 3

2

使用 RestKit+CoreData 时必须使用块,并忘记路由器设置:

NSString *postUrl = @"/someurl/newelement";    
[ [RKObjectManager sharedManager] loadObjectsAtResourcePath:postUrl usingBlock:^(RKObjectLoader* loader) {
    loader.serializationMIMEType = RKMIMETypeJSON;

    loader.delegate = nil;
    loader.targetObject = nil;
    loader.method= RKRequestMethodPOST; // change to GET, POST, PUT etc
}];
于 2012-07-16T11:31:56.103 回答
1

由于您不包含 UI 代码,因此很难完全诊断此问题,但是当您重新启动应用程序时显示更新可能会发生一件事,那就是您没有正确同步各个线程之间的更改本地托管对象上下文。RestKit 有自己的托管对象上下文,因为它不在主 UI 线程上运行。

在这个 Apple 文档中介绍了在 Core Data 中使用多线程的概念:http: //developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html但它的要点是您需要注册通知NSManagedObjectContextDidSaveNotification,然后mergeChangesFromContextDidSaveNotification:在 UI 线程的托管对象上下文上调用以安全地合并在 RestKit 线程上完成的更改。

请记住,通知将发布在 RestKit 线程上,因此您可能必须在主 UI 线程上运行更新,例如在接收通知的方法中如下所示:

[self.managedObjectContextForMainThread performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES];

属性NSManagedObjectContext* managedObjectContextForMainThread已正确初始化以指向 UI 线程的托管对象上下文的位置。

希望这会有所帮助(如果您还没有完全放弃 RestKit ......)

于 2012-11-01T16:52:10.130 回答
0

我仍在使用稍旧版本的 Restkit。但一个关键要素是必须定义主键属性。这样 Restkit 就可以让你的本地存储对象和服务器对象保持同步。

在您的情况下,为您的目标对象定义映射时,您会这样做:goalMapping.primaryKeyAttribute = @"identifier";

于 2012-06-02T07:37:00.373 回答