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

发布于 2024-12-18 10:58:05 字数 1453 浏览 1 评论 0原文

我对 Objective-C 比较陌生,正在尝试使用 RestKit 从 Web 服务接收 JSON 响应。我已成功将数据接收回我的应用程序,查看响应如下所示:

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

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

所以我的问题是:

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

我的翻译对象

@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

}

I am relatively new to Objective-C and am attempting to use RestKit to receive a JSON response from a web service. I have successfully received the data back to my application, which looks like this viewing the response:

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

I would like to map this translation to my "Translation" object in my application, but have tried a few different ways but am not sure how to achieve this.

So my questions are:

  1. How can I map this response to my Translation object
  2. Am I doing this correctly, creating a method to complete this call outwit my view controller?

My Translation Object

@implementation Translation  

@synthesize identifier = _identifier;
@synthesize translation = _translation;

- (NSDictionary*)elementToPropertyMappings {  
return [NSDictionary dictionaryWithKeysAndObjects:  
        @"id", @"identifier",  
        @"translation", @"translation",
        nil];  
}  

@end

My Translate Method

- (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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅紫色的梦幻 2024-12-25 10:58:05

您的代码片段似乎有点过时了。我强烈建议您按顺序阅读最新的对象映射指南利用 RestKit 发挥其最大潜力 - 尤其是无 KVC 映射部分。

编辑:

为了使用 RestKit 发布对象并接收答案,我们定义一个 TranslationRequest 类来保存我们的请求和结果。 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 日志来看,这应该可行。

The snippet of your code seems a bit outdated. I strongly recommend reading the newest Object Mapping guide in order to leverage RestKit into it's fullest potential - especially the part Mapping without KVC.

Edit:

In order to post an object with RestKit and receive back an answer, we define a TranslationRequest class that will hold our request & Translation to hold our response.

Firstly, we set up our RKObjectManager and mappings (i usually do this in my 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];

This should be enough of the necessary setup. We can call our backend anywhere in the code (e.g. in any controller) like this:

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

Try this approach and let me know if you need any assistance.. I was not able to test it fully as i don't have any suitable backend that will return the responses, but judging from the RestKit log this should work.

ゝ偶尔ゞ 2024-12-25 10:58:05

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

RestKit 似乎有封装四种不同 JSON 解析器的原生对象。但是,我建议谨慎,因为他们似乎假设顶级解析对象始终是字典。

另一方面,您问题中的示例不是有效的 JSON。它应该看起来像这样:

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

You need to pass the returned JSON string into a JSON parser. I use SBJSON. You can then use the resulting dictionary to populate the properties of your object.

RestKit seems to have native objects that encapsulate four different JSON parsers. However, I'd advise caution because they seem to assume that the top level parsed object will always be a dictionary.

As another aside, the example in your question is not valid JSON. It should look like this:

{"id":"1","Translation":"Test"}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文