RestKit valueTransformer未被调用

时间:2014-11-12 06:04:27

标签: ios objective-c restkit restkit-0.20 nsvaluetransformer

我正在使用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说我可以设置它。但那为什么不编译?

3 个答案:

答案 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。