如何在通过 RESTKIT 映射之前更改 JSON

发布于 2024-12-23 10:16:32 字数 1630 浏览 1 评论 0原文

我正在使用 RESTKIT 来映射从服务器返回的 JSON。

从服务器获取的 JSON 结果如下

{"term":"Zh","results":{"users":[{"id":{"$oid":"4ebe59970a614e0019000055"},"term":"some text","score":1}]}

如何将上面的 JSON 结果转换为下面的:

{"results":{"users":[{"uid":"4ebe59970a614e0019000055","text":"some text"}]}

另外,我可以在哪里执行此操作,以便 RESTKIT 映射将使用转换后的 JSON 而不是初始的 JSON?

下面是我用来管理 JSON 和映射的加载器类

-(void)getObjects
{
    RKObjectManager *sharedManager = [RKObjectManager sharedManager];
    [sharedManager loadObjectsAtResourcePath:self.resourcePath delegate:self];
}

- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
    NSLog(@"Loaded PAYLOAD successfully for %@, with response %@", self.resourcePath , [response bodyAsString]  );
}


- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects 
{
}


+ (void)setManagerAndMappings
{
    RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:SERVER_URL];
    RKObjectMappingProvider* provider = [[RKObjectMappingProvider new] autorelease];

    //User Object Mapping
    RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[User class]];
    [userMapping mapKeyPath:@"_id" toAttribute:@"uid"];

    [userMapping mapAttributes:@"avatar_url",@"created_at",@"email",@"name",@"nickname",@"follower_count",@"following_count",@"answer_count",@"new_notification_count",@"new_questions_count",@"is_following",@"facebook_configured",@"twitter_configured",@"description",@"approved",@"type", nil];
    [provider setMapping:userMapping forKeyPath:@"user"];

}

I am using RESTKIT to map the JSON returned from server.

The JSON result obtained from server is as follows

{"term":"Zh","results":{"users":[{"id":{"$oid":"4ebe59970a614e0019000055"},"term":"some text","score":1}]}

How can I convert the above JSON result to the below:

{"results":{"users":[{"uid":"4ebe59970a614e0019000055","text":"some text"}]}

Also, where can I do this so that the RESTKIT mapping will use the converted JSON instead of the initial one?

Below is the loader class that I am using to manage the JSON and mappings

-(void)getObjects
{
    RKObjectManager *sharedManager = [RKObjectManager sharedManager];
    [sharedManager loadObjectsAtResourcePath:self.resourcePath delegate:self];
}

- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
    NSLog(@"Loaded PAYLOAD successfully for %@, with response %@", self.resourcePath , [response bodyAsString]  );
}


- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects 
{
}


+ (void)setManagerAndMappings
{
    RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:SERVER_URL];
    RKObjectMappingProvider* provider = [[RKObjectMappingProvider new] autorelease];

    //User Object Mapping
    RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[User class]];
    [userMapping mapKeyPath:@"_id" toAttribute:@"uid"];

    [userMapping mapAttributes:@"avatar_url",@"created_at",@"email",@"name",@"nickname",@"follower_count",@"following_count",@"answer_count",@"new_notification_count",@"new_questions_count",@"is_following",@"facebook_configured",@"twitter_configured",@"description",@"approved",@"type", nil];
    [provider setMapping:userMapping forKeyPath:@"user"];

}

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

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

发布评论

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

评论(6

紫﹏色ふ单纯 2024-12-30 10:16:32

@Shocks 的答案很吸引人,不幸的是它对于 0.20 之前的版本有效。

无论如何,类似的解决方案也适用于 0.20,使用 RKSerialization 的实现:

@interface ORRKJsonSerialization : NSObject <RKSerialization>
@end

@implementation ORRKJsonSerialization

+ (id)objectFromData:(NSData *)data error:(NSError **)error
{
    id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
    // change your data before mapping
    return result;
}

+ (NSData *)dataFromObject:(id)object error:(NSError **)error
{
    return [NSJSONSerialization dataWithJSONObject:object options:0 error:error];
}

@end

在设置过程中实现:

[RKMIMETypeSerialization registerClass:[ORRKJsonSerialization class] forMIMEType:@"application/json"];

HTH

@Shocks answer is appealing, unfortunately it is valid a for version before 0.20.

Anyway, a similar solution is available for 0.20 too, using an implementation of RKSerialization:

@interface ORRKJsonSerialization : NSObject <RKSerialization>
@end

and implementing

@implementation ORRKJsonSerialization

+ (id)objectFromData:(NSData *)data error:(NSError **)error
{
    id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
    // change your data before mapping
    return result;
}

+ (NSData *)dataFromObject:(id)object error:(NSError **)error
{
    return [NSJSONSerialization dataWithJSONObject:object options:0 error:error];
}

@end

then during the setup:

[RKMIMETypeSerialization registerClass:[ORRKJsonSerialization class] forMIMEType:@"application/json"];

HTH

淡写薰衣草的香 2024-12-30 10:16:32

RKObkectLoaderDelegate 中有一个 willMapData: 选择器 在解析完成后立即调用。 mappableData 参数是可变的,所以我想您可以在对象映射发生之前更改数据。

There is a willMapData: selector in the RKObkectLoaderDelegate that is invoked just after parsing has completed. The mappableData argumet is mutable, so i guess you can change the data just before the object mapping will take place.

不忘初心 2024-12-30 10:16:32

使用RKObjectRequestOperation.setWillMapDeserializedResponseBlock:

快速:

    let request = RKObjectManager.sharedManager().requestWith...
    let operation = RKObjectManager.sharedManager().managedObjectRequestOperationWithRequest(request, managedObjectContext: context, success: { operation, result in
        // success
    }, failure: { operation, error in
        // failure
    })
    operation.setWillMapDeserializedResponseBlock { deserializedResponse -> AnyObject! in
        // Here to transform response
        return transformResponse(deserializedResponse)
    }
    RKObjectManager.sharedManager().enqueueObjectRequestOperation(operation)

use RKObjectRequestOperation.setWillMapDeserializedResponseBlock:.

In swift:

    let request = RKObjectManager.sharedManager().requestWith...
    let operation = RKObjectManager.sharedManager().managedObjectRequestOperationWithRequest(request, managedObjectContext: context, success: { operation, result in
        // success
    }, failure: { operation, error in
        // failure
    })
    operation.setWillMapDeserializedResponseBlock { deserializedResponse -> AnyObject! in
        // Here to transform response
        return transformResponse(deserializedResponse)
    }
    RKObjectManager.sharedManager().enqueueObjectRequestOperation(operation)
茶花眉 2024-12-30 10:16:32

对我来说,唯一的解决方案是在服务器级别修改返回的对象。
如果不能,只需返回服务器的映射即可。

For me the only solution is to modify the returned object at the server level.
If you can't,just map that returns the server.

眉目亦如画i 2024-12-30 10:16:32

您可以注册自己的解析器。我必须这样做才能修改和清理遗留系统中的一些 JSON。

[[RKParserRegistry sharedRegistry] setParserClass:[MyJSONParser class]
                                          forMIMEType:@"application/json"];

然后创建你自己的:

#import <RestKit/RestKit.h>
#import <RestKit/RKJSONParserJSONKit.h>
#import <RestKit/JSONKit.h>
#import <RestKit/RKLog.h>

@interface EFJSONParser : RKJSONParserJSONKit
- (NSDictionary *)objectFromString:(NSString *)string error:(NSError **)error;
@end

You can register your own parser. I had to do this to modify and clean-up some JSON from a legacy system.

[[RKParserRegistry sharedRegistry] setParserClass:[MyJSONParser class]
                                          forMIMEType:@"application/json"];

And then create your own:

#import <RestKit/RestKit.h>
#import <RestKit/RKJSONParserJSONKit.h>
#import <RestKit/JSONKit.h>
#import <RestKit/RKLog.h>

@interface EFJSONParser : RKJSONParserJSONKit
- (NSDictionary *)objectFromString:(NSString *)string error:(NSError **)error;
@end
与君绝 2024-12-30 10:16:32

编辑 JSOn 的响应非常困难。更好的方法是只在服务器端进行更改,如 @beber 所说

It's very difficult to editing the response of JSOn. the better way is only to do changes in server side as said by @beber

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