我正在使用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的例子都说了同样的话。所有示例都设置valueTransformer
对象的AttributeMapping
属性。即使RestKit Class Reference说我可以设置它。但那为什么不编译?
答案 0 :(得分:2)
所以我设法弄清楚问题是什么。
我的podfile配置为使用RestKit 0.20.3。然后我添加了RKValueTransformers
作为另一个Pod。但是,RestKit 0.20.3及更早版本带有自己版本的RKValueTransformer(.h和.m)文件。而那些旧版本的RestKit并不支持添加自己的变形金刚,因为它没有使用较新的RKValueTransformers
库。
当我将RestKit版本升级到最新版本时(实际上任何高于0.21.0的版本都可以),事情开始正常。我不需要添加pod RKValueTransformers,因为它会自动添加为RestKit的依赖项。
答案 1 :(得分:1)
请使用insertValueTransformer:atIndex:
代替addValueTransformer:
,以便您可以在列表的开头而不是结尾添加它。
答案 2 :(得分:0)
在swift中,我可以成功创建一个值变换器。
它的目的是只为我的模型添加一个时间戳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
参数,而是访问memory
outputValue
参数的属性。
注意:我在我的属性映射的另一侧使用@self
的通用keyPath,以便我可以将此映射用于具有{{1}的各种类} property。