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

我正在尝试使用RestKit和Rails来实现魔法。 我正在使用Rails 3.1.1和RestKit 0.9.3(不是主分支)。 我在我的iOS应用程序中使用核心数据,所以我试图设置应用程序使用尽可能多的RestKit魔术来与rails应用程序进行交互。

但是,我有一个问题试图POST一个新的对象到我的服务器来创build。 我已经成功地把对象取下来了。 这是我的代码来做到这一点:

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"]; 

这似乎对我很好。 现在,我想将新创build的对象发送回服务器。

 - (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参数以及? 帮助将不胜感激,谢谢!

更新
这是服务器响应 – 它的工作原理,但似乎参数有点搞砸了? (我input的标题是:“由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) 

我认为inverseMappingselect器应该足以进行序列化映射

 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产生的警告是由于服务器响应缺less根KeyPath(作为裸数组返回的)而引起的。 为了解决这个问题,我们需要告诉RestKit使用特定的映射来映射响应:

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

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

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

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