使用RestKit和Objective-C将JSON响应映射到对象

时间:2011-11-29 10:52:28

标签: objective-c xcode4 xcode4.2 restkit

我是Objective-C的新手,我正在尝试使用RestKit从Web服务接收JSON响应。我已成功将数据收回我的应用程序,看起来像这样查看响应:

{id:"1","Translation":"Test"}

我想在我的应用程序中将此翻译映射到我的“翻译”对象,但尝试了几种不同的方法,但我不知道如何实现这一目标。

所以我的问题是:

  1. 如何将此回复映射到我的翻译对象
  2. 我是否正确地执行此操作,创建一种方法来完成此调用,而不是我的视图控制器?
  3. 我的翻译对象

    @implementation Translation  
    
    @synthesize identifier = _identifier;
    @synthesize translation = _translation;
    
    - (NSDictionary*)elementToPropertyMappings {  
    return [NSDictionary dictionaryWithKeysAndObjects:  
            @"id", @"identifier",  
            @"translation", @"translation",
            nil];  
    }  
    
    @end
    

    我的翻译方法

    - (NSString *)performTranslation:(NSString *)translation
    {
    
    NSString *data = [[NSString alloc] initWithFormat:@"{\"SourceId\": \"%@\",\"RegionTag\": \"%@\",\"InputString\": \"%@\"}", @"1", @"Glasgow", translation];
    NSString *post = data;
    
    RKRequest *MyRequest = [[RKRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"http://my.url.com/Translation/Translate"]];
    MyRequest.method = RKRequestMethodPOST;
    MyRequest.HTTPBodyString = post;
    MyRequest.additionalHTTPHeaders = [[NSDictionary alloc] initWithObjectsAndKeys:@"application/json", @"Content-Type", @"application/json", @"Accept", nil];
    [MyRequest send];
    
    RKResponse *Response = [MyRequest sendSynchronously];
    
    return Response.bodyAsString; <--- looking to map this to translation object here
    
    }
    

2 个答案:

答案 0 :(得分:4)

您的代码片段似乎有点过时了。我强烈建议您阅读最新的Object Mapping guide,以便充分利用RestKit的潜力 - 尤其是没有KVC的映射

编辑:

为了使用RestKit发布一个对象并收到一个答案,我们定义一个TranslationRequest类来保存我们的请求&amp; Translation我们的回复。

首先,我们设置了RKObjectManager和映射(我通常在我的AppDelegate中执行此操作):

RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:kOurBaseUrl];
[manager setSerializationMIMEType:RKMIMETypeJSON];
//this is a singleton, but we keep the manager variable to avoid using [RKObjectManager sharedManager] all the time

//Here we define a mapping for the request. Note: We define it as a mapping from JSON to entity and use inverseMapping selector later.
RKObjectMapping *translationRequestMapping = [RKObjectMapping mappingForClass:[TranslationRequest class]];
[translationRequestMapping mapKeyPath:@"RegionTag" toAttribute:@"regionTag"];
...
[[manager mappingProvider] setSerializationMapping:[translationRequestMapping inverseMapping] forClass:[TranslationRequest class]];

//now we define the mapping for our response object
RKObjectMapping *translationMapping = [RKObjectMapping mappingForClass:[Translation class]];
[translationMapping mapKeyPath:@"id" toAttribute:@"identifier"];
[translationMapping mapKeyPath:@"Translation" toAttribute:@"translation"];
[[manager mappingProvider] addObjectMapping:mapping];

//finally, we route our TranslationRequest class to a given endpoint
[[manager router] routeClass:[TranslationRequest class] toResourcePath:kMyPostEndpoint];

这应该足够必要的设置。我们可以在代码中的任何地方调用我们的后端(例如在任何控制器中),如下所示:

//we create new TranslationRequest
TranslationRequest *request = [[TranslationRequest alloc] init];
[request setRegionTag:@"Hello"];
....
//then we fetch the desired mapping to map our response with
RKObjectMapping *responseMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:class]
//and just call it. Be sure to let 'self' implement the required RKObjectManagerDelegate protocol
[[RKObjectManager sharedManager] postObject:request mapResponseWith:responseMapping delegate:self];]

尝试这种方法并告诉我你是否需要任何帮助..我无法完全测试它,因为我没有任何合适的后端会返回响应,但从RestKit日志判断这应该有效。

答案 1 :(得分:3)

您需要将返回的JSON字符串传递给JSON解析器。我使用SBJSON。然后,您可以使用生成的字典填充对象的属性。

RestKit似乎有本机对象封装了四个不同的JSON解析器。但是,我建议谨慎,因为他们似乎认为顶级解析对象将始终是字典。

另外,您的问题中的示例不是有效的JSON。它应该是这样的:

{"id":"1","Translation":"Test"}