RestKit不会在64位模拟器中映射BOOL

时间:2014-03-04 14:54:55

标签: ios restkit

我需要帮助理解下面的错误。

我的NSObject中有一个BOOL定义为:

@property (nonatomic) BOOL isOpen;

在我的reskit类中,我使用:

 [mapping addAttributeMappingsFromDictionary:@{......
                                             @"isOpen":      @"isOpen"
                                             ......}];

使用我的iPhone4S和原装iPhone5,我的所有测试都运行了好几周。作为我在64位设备上在模拟器上测试的最后一次测试,我收到以下错误:

 restkit.object_mapping:RKMappingOperation.m:440 Failed transformation of value at keyPath 'isOpen' to representation of type '__NSCFBoolean': Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 "Failed transformation of value '1' to __NSCFBoolean: none of the 2 value transformers consulted were successful." UserInfo=0x10cba1c00 {NSLocalizedDescription=Failed transformation of value '1' to __NSCFBoolean: none of the 2 value transformers consulted were successful., detailedErrors=(
"Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 \"The given value is not already an instance of '__NSCFBoolean'\" UserInfo=0x10cb86d30 {NSLocalizedDescription=The given value is not already an instance of '__NSCFBoolean'}",
"Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3000 \"Expected an `inputValue` of type `NSNull`, but got a `__NSCFNumber`.\" UserInfo=0x10cbeb400 {NSLocalizedDescription=Expected an `inputValue` of type `NSNull`, but got a `__NSCFNumber`.}"
 )}

3 个答案:

答案 0 :(得分:3)

正如Mikael所说,在64位平台上运行的RestKit存在一些小故障,阻止了从NSNumber到BOOL的默认转换(反之亦然)。

但是,借助RestKit Value Transformers模块化架构,有一种方法可以实现这一目标。因此,您只需创建一个专用的变换器类并使用RestKit默认变换器注册它。

这就是变压器的样子:

@interface RKCustomBOOLTransformer : NSObject  <RKValueTransforming>

+ (instancetype)defaultTransformer;

@end

@implementation RKCustomBOOLTransformer

+ (instancetype)defaultTransformer {
    return [RKCustomBOOLTransformer new];
}

- (BOOL)validateTransformationFromClass:(Class)inputValueClass toClass:(Class)outputValueClass {
    return ([inputValueClass isSubclassOfClass:[NSNumber class]] &&
         [outputValueClass isSubclassOfClass:[NSNumber class]]);
}

- (BOOL)transformValue:(id)inputValue toValue:(id *)outputValue ofClass:(Class)outputValueClass error:(NSError **)error {
    RKValueTransformerTestInputValueIsKindOfClass(inputValue, (@[ [NSNumber class] ]), error);
    RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, (@[ [NSNumber class] ]), error);

    if (strcmp([inputValue objCType], @encode(BOOL)) == 0) {
        *outputValue = inputValue?@(1):@(0);
    } else if (strcmp([inputValue objCType], @encode(int)) == 0) {
        *outputValue = ([inputValue intValue] == 0) ? @(NO) : @(YES);
    }
    return YES;
}

@end

你这样注册:

[[RKValueTransformer defaultValueTransformer]
 insertValueTransformer:[RKCustomBOOLTransformer defaultTransformer] atIndex:0];

在定义映射之前注意注册。

答案 1 :(得分:2)

这是由我的JSON使用1和0而不是true和false引起的。由于某种原因,64位设备将获取1和0作为NSString但32位设备将作为NSNumber。一个设备会将其更改为BOOL而不是另一个设备。

如果我将引号放在JSON的1和0周围,那么它就可以了。

答案 2 :(得分:2)

我必须按照与塞尔吉奥的回答相同的方式做一些事情,但就我而言,JSON的形成类似于:"private":0

@implementation RPBooleanTransformer

+ (instancetype)defaultTransformer {
  return [[RPBooleanTransformer alloc] init];
}

- (BOOL)validateTransformationFromClass:(Class)inputValueClass toClass:(Class)outputValueClass {
  return ([inputValueClass isSubclassOfClass:NSClassFromString(@"__NSCFNumber")] &&
          [outputValueClass isSubclassOfClass:NSClassFromString(@"__NSCFBoolean")]);
}

- (BOOL)transformValue:(id)inputValue toValue:(id *)outputValue ofClass:(Class)outputValueClass error:(NSError **)error {
  RKValueTransformerTestInputValueIsKindOfClass(inputValue, (@[ NSClassFromString(@"__NSCFNumber") ]), error);
  RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, (@[ NSClassFromString(@"__NSCFBoolean") ]), error);

  if ([inputValue isKindOfClass:NSClassFromString(@"__NSCFNumber")]) {
    *outputValue = ([inputValue boolValue] == YES) ? @(YES) : @(NO);
  } else if ([inputValue isKindOfClass:NSClassFromString(@"__NSCFBoolean")]) {
    *outputValue = [inputValue isEqual:@(YES)] ? @1 : @0;
  }
  return YES;
}