在RestKit中将NSTimeZone转换为Json

时间:2014-02-05 03:35:57

标签: objective-c restkit restkit-0.20

在我的iOS应用程序中,我有一个timeZone属性为NSTimeZone的对象。我想使用RestKit 0.22.0将其作为JSON(以及其他数据)发布。

我设置了一个值变换器块,但它导致了一个错误,我一直无法弄清楚。

RKObjectMapping *eventMapping = [RKObjectMapping requestMapping];

RKValueTransformer *timeZoneTransformer = [RKBlockValueTransformer valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class sourceClass, __unsafe_unretained Class destinationClass) {

        // We transform a `NSTimeZone` into `NSString`
        return ([sourceClass isSubclassOfClass:[NSTimeZone class]] && [destinationClass isSubclassOfClass:[NSString class]]);

    } transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, Class outputValueClass, NSError *__autoreleasing *error) {

        // Validate the input and output
        RKValueTransformerTestInputValueIsKindOfClass(inputValue, [NSTimeZone class], error);
        RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, [NSString class], error);

        // Perform the transformation
        *outputValue = [((NSTimeZone *)inputValue) name];
        return YES;
    }];

    RKAttributeMapping *timeZoneAttributeMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"timeZone" toKeyPath:@"event.zone"];

    timeZoneAttributeMapping.valueTransformer = timeZoneTransformer;

    [eventMapping addPropertyMapping:timeZoneAttributeMapping];

我想提交给我的API的值是区域的地缘政治ID。对于纽约,它将是America\New_York

我在Xcode中添加了一个断点,以显示异常发生的位置。它发生在RK库的以下文件中,在此行return [NSJSONSerialization dataWithJSONObject:object options:0 error:error];

#import "RKNSJSONSerialization.h"

@implementation RKNSJSONSerialization

+ (id)objectFromData:(NSData *)data error:(NSError **)error
{
    return [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
}

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

例外是'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSTimeZone)'

有趣的是,当Xcode在我上面提到的return语句中断时,在变量视图中,object消息dataFromObject参数实际上包含了值(America/New_York)我想要提交给服务器。所以,它似乎有效。

此外,在变量视图中,error的{​​{1}}参数的值为dataFromObject

1 个答案:

答案 0 :(得分:0)

仔细检查Xcode的变量视图中的变量后,我试图映射到JSON的NSTimeZone对象实际上并没有映射到NSString。我认为这是正确的映射,因为变量的值是它应该是的(即America/New_York)。但是,类型仍为NSTimeZone。因此,根本没有调用转换代码块。

然后我在RKCLLocationValueTransformer示例here中看到了此示例代码。

RKObjectMapping *userRequestMapping = [RKObjectMapping requestMapping];
[userRequestMapping addAttributeMappingsFromArray:@[ @"name" ]];
RKAttributeMapping *attributeMapping = [RKAttributeMapping
    attributeMappingFromKeyPath:@"location" toKeyPath:@"location"];
attributeMapping.propertyValueClass = [NSDictionary class];
attributeMapping.valueTransformer = [RKCLLocationValueTransformer
    locationValueTransformerWithLatitudeKey:@"latitude" longitudeKey:@"longitude"];
[userRequestMapping addPropertyMapping:attributeMapping];

NSError *error = nil;
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor
    requestDescriptorWithMapping:userRequestMapping objectClass:[User class]
    rootKeyPath:@"user" method:RKRequestMethodAny];

问题在于我没有指定propertyValueClass属性。

attributeMapping.propertyValueClass = [NSDictionary class];

propertyValueClass属性指定希望将映射值表示为或转换为的类型。

代码应如下所示。

RKAttributeMapping *timeZoneAttributeMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"timeZone" toKeyPath:@"event.zone"];

timeZoneAttributeMapping.propertyValueClass = [NSString class];

timeZoneAttributeMapping.valueTransformer = timeZoneTransformer;

[eventMapping addPropertyMapping:timeZoneAttributeMapping];

Here是此属性文档的链接。

有关NSInvalidArgumentException原因的详细信息,请here