RestKit valueTransformer 未被调用
Posted
技术标签:
【中文标题】RestKit valueTransformer 未被调用【英文标题】:RestKit valueTransformer not being called 【发布时间】:2014-11-12 06:04:26 【问题描述】:我正在使用 RestKit 与我的 JSON 端点通信。端点返回以“毫秒数”为单位的 UNIX 时间戳。但是 RestKit 的默认转换器假定它是“秒数”,我在 NSDate 中得到了错误的值。
于是我环顾四周,发现我需要使用自定义的 valueTransformer 来告诉 RestKit 如何转换我的时间戳。这是我的代码。
+ (RKBlockValueTransformer*) timeIntervalInMillisecondsSince1970TwoWayTransformer
return [RKBlockValueTransformer valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class sourceClass, __unsafe_unretained Class destinationClass)
// This transformer handles `NSNumber` <-> `NSDate` transformations
NSLog(@"checking new transformer");
return (([sourceClass isSubclassOfClass:[NSNumber class]] && [destinationClass isSubclassOfClass:[NSDate class]]) ||
([sourceClass isSubclassOfClass:[NSDate class]] && [destinationClass isSubclassOfClass:[NSNumber class]]));
transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, __unsafe_unretained Class outputValueClass, NSError *__autoreleasing *error)
NSLog(@"transforming");
RKValueTransformerTestInputValueIsKindOfClass(inputValue, (@[ [NSNumber class], [NSDate class] ]), error);
RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, (@[ [NSNumber class], [NSDate class] ]), error);
if ([outputValueClass isSubclassOfClass:[NSDate class]])
if ([inputValue isKindOfClass:[NSNumber class]])
*outputValue = [NSDate dateWithTimeIntervalSince1970:[inputValue doubleValue] / 1000];
else if ([outputValueClass isSubclassOfClass:[NSNumber class]])
*outputValue = @((NSInteger)[inputValue timeIntervalSince1970] * 1000);
return YES;
];
然后我将这个转换器添加到 RestKit 的默认转换器中。
RKValueTransformer* transformer = [self timeIntervalInMillisecondsSince1970TwoWayTransformer];
[[RKValueTransformer defaultValueTransformer] addValueTransformer:transformer];
但是,我的转换器永远不会被调用。我在其中写的NSLog
语句永远不会被执行!
然后我尝试了这个——像这样在attributeMapping上写一个转换器:
RKValueTransformer* transformer = [self timeIntervalInMillisecondsSince1970TwoWayTransformer];
RKAttributeMapping *tokenExpiryMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"access_token_expiration" toKeyPath:@"accessTokenExpirationDate"];
tokenExpiryMapping.valueTransformer = transformer;
[userMapping addPropertyMapping:tokenExpiryMapping];
但是当我这样做时代码不会编译。它说“在 'RKAttributeMapping *' 类型的对象上找不到属性 valueTransformer”。我不明白这一点。我在互联网上看到的所有示例,包括带有RestKit's documentation 的示例都说同样的话。所有示例都设置了AttributeMapping
对象的valueTransformer
属性。甚至RestKit Class Reference 说我可以设置它。但是为什么不编译呢?
【问题讨论】:
【参考方案1】:所以我终于弄清楚了问题所在。
我的 podfile 配置为使用 RestKit 0.20.3。然后我添加了RKValueTransformers
作为另一个 Pod。但是,RestKit 0.20.3 和更早版本带有自己的 RKValueTransformer(.h 和 .m)文件版本。而且那些旧版本的 RestKit 不支持添加您自己的 Transformer,因为它不使用较新的 RKValueTransformers
库。
当我将我的 RestKit 版本升级到最新版本时(实际上任何高于 0.21.0 的版本都可以),一切都开始正常了。我不需要添加 pod RKValueTransformers,因为它会自动添加为 RestKit 的依赖项。
【讨论】:
【参考方案2】:考虑使用insertValueTransformer:atIndex:
而不是addValueTransformer:
,这样您就可以将其添加到列表的开头而不是结尾。
【讨论】:
我想在NSNumber
中添加一个转换器NSString
来处理32 位溢出。在我进行此更改之前没有调用 Transformer。【参考方案3】:
我很快就可以成功地创建一个价值转换器。
它的目的只是为我的模型添加一个时间戳downloadedOn
,所以我根本不使用inputValue
:
let downloadedMapping = RKAttributeMapping(fromKeyPath: "@self", toKeyPath: "downloadedOn")
downloadedMapping.valueTransformer = RKBlockValueTransformer(validationBlock: nil) _, outputValue, _, error -> Bool in
outputValue.memory = NSDate()
return true
myMapping.addPropertyMapping(downloadedMapping)
对我来说最大的警告是我应该如何将值写入outputValue
指针,直到我发现我不必使用inout
参数而是访问@987654327 的memory
属性@参数。
注意:我将@self
的通用keyPath 用于我的属性映射的另一端,以便我可以将此映射用于具有downloadedOn
属性的各种类。
【讨论】:
以上是关于RestKit valueTransformer 未被调用的主要内容,如果未能解决你的问题,请参考以下文章
在 xcodebuild 期间未找到 RestKit/RestKit.h' 文件错误
xCode 4.3 使用 RestKit 归档项目失败:#import <RestKit/RestKit.h> Not found
RestKit 0.20:restkit 对象映射使属性映射加倍