如何使用RestKit将对象发布到rails?

时间:2011-12-07 00:58:07

标签: iphone ruby-on-rails ios serialization restkit

我正试图通过RestKit和Rails实现神奇。我正在使用Rails 3.1.1和RestKit 0.9.3(不是主分支)。我在我的iOS应用程序中使用Core Data,所以我正在尝试设置应用程序以尽可能多地使用RestKit魔法与rails应用程序进行交互。

但是,我在尝试将新对象发布到要创建的服务器时遇到问题。我成功地把对象搞得一团糟。这是我的代码:

RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://IP_ADDRESS"];
manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"magikarp.sqlite"];
manager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
manager.acceptMIMEType = RKMIMETypeJSON; 
manager.serializationMIMEType = RKMIMETypeJSON; 

///
/// Setup Routing
///

RKObjectRouter *router = [[RKObjectRouter alloc] init];
[router routeClass:[List class] toResourcePath:@"/lists/(listID)"];
[router routeClass:[List class] toResourcePath:@"/lists" forMethod:RKRequestMethodPOST];
manager.router = router;

///
/// Setup mapping for my "List" object; a subclass of NSManagedObject
///
RKManagedObjectMapping *listMapping = [RKManagedObjectMapping mappingForClass:[List class]];
listMapping.primaryKeyAttribute = @"listID";

[listMapping mapAttributes:@"title", nil];
[listMapping mapKeyPath:@"id" toAttribute:@"listID"];
[manager.mappingProvider setMapping:listMapping forKeyPath:@"list"];

这似乎对我有用。现在,我想将新创建的对象POST回服务器。

- (void)createList:(NSString *)listName {
    List *newList = [List object];
    newList.title = listName;
    [[RKObjectManager sharedManager] postObject:newList delegate:self]; 
}

我用我想要新列表的名称来调用此方法。调用此方法,但我收到此错误:

2011-12-06 19:24:17.822 Magikarp[13921:14c1b] W restkit.object_mapping:RKObjectMapper.m:74 Adding mapping error: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] E restkit.network:RKObjectLoader.m:190 Encountered errors during mapping: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] Hit error: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "Could not find an object mapping for keyPath: ''" UserInfo=0x6bb9da0 {=RKObjectMapperKeyPath, NSLocalizedDescription=Could not find an object mapping for keyPath: ''}

我完成映射的尝试是:

RKObjectMapping *listSerializationMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[listSerializationMapping mapKeyPath:@"title" toAttribute:@"title"];
[listSerializationMapping mapKeyPath:@"ListID" toAttribute:@"id"];
[manager.mappingProvider setSerializationMapping:listSerializationMapping forClass:[List class]];

(这给出了上述错误)。我知道有一种非常简单的方法可以做到这一点,但没有一个例子有这个代码,并且所有文档似乎都已过时了......你是否也必须将信息作为POST参数发送?感谢帮助,谢谢!

更新
这是服务器响应 - 它可以工作,但看起来参数有点搞砸了? (我输入的标题是:“用iPhone 2制作!”)

Started POST "/lists" for 129.21.86.32 at 2011-12-07 09:34:43 -0500
  Processing by ListsController#create as JSON
  Parameters: {"id"=>0, "title"=>"Made from the iPhone 2!", "list"=>{"id"=>0, "title"=>"Made from the iPhone 2!"}}
WARNING: Can't verify CSRF token authenticity
WARNING: Can't mass-assign protected attributes: id
   (0.3ms)  BEGIN
  SQL (0.9ms)  INSERT INTO "lists" ("created_at", "title", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["created_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00], ["title", "Made from the iPhone 2!"], ["updated_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00]]
   (16.4ms)  COMMIT
Completed 201 Created in 77ms (Views: 1.8ms | ActiveRecord: 21.9ms)

2 个答案:

答案 0 :(得分:8)

我认为inverseMapping选择器应足以进行序列化映射

RKManagedObjectMapping *listMapping = [RKManagedObjectMapping mappingForClass:[List class]];
listMapping.primaryKeyAttribute = @"listID";

[listMapping mapAttributes:@"title", nil];
[listMapping mapKeyPath:@"id" toAttribute:@"listID"];
[manager.mappingProvider setMapping:listMapping forKeyPath:@"list"];
//this should be enough
[manager.mappingProvider setSerializationMapping:[listMapping inverseMapping] forClass:[List class]];

编辑:

根据我们的聊天对话,RestKit产生的警告是由于服务器响应缺少根KeyPath(作为裸数组返回)引起的。要解决这个问题,我们需要告诉RestKit使用特定的映射来映射响应:

mapping = [[[RKObjectManager sharedManager] mappingProvider] mappingForKeyPath:@"list"];
[[RKObjectManager sharedManager] postObject:newList mapResponseWith:mapping delegate:self];

答案 1 :(得分:2)

这是来自RestKit文档。有一种方便的方法可以设置映射和序列化映射

[[RKObjectManager sharedManager].mappingProvider registerMapping:mapping withRootKeyPath:@"person"];

这将为您调用setMapping:forKeyPath:,然后生成序列化映射并设置根keyPath。