在我的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
。
答案 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。