Search code examples
iosparametersbooleannsdictionaryrestkit

Boolean value in the NSDictionary serialized as true/false for x-www-form-urlencoded


RestKit version: 0.27.0

Is there any way how to let RestKit to serialize the boolean value stored in NSDictionary to x-www-form-urlencoded parameters?

I have NSDictionary filled with values, it is propagated to the encoded string:

product=ACCOUNT&rejected=1&type=NUMBER_OF_LOGINS_MONTH

But I need true/false instead of 1 or 0 as the value for rejected parameter.

Is there any way how to use class specification similar to RKAttributeMapping's propertyValueClass to override the default type NSNumber? Also NSNumber is internally implemented as __NSCFBoolean. Is it possible to use this information to serialize the value as true/false?


Solution

  • I have subclassed RKURLEncodedSerialization and copied the implementation from RKAFQueryStringFromParametersWithEncoding:

        static NSString * TSNRKAFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) {
            NSMutableArray *mutablePairs = [NSMutableArray array];
            for (TSNRKAFQueryStringPair *pair in TSNRKAFQueryStringPairsFromDictionary(parameters)) {
    
                if([NSStringFromClass([pair.value class]) isEqualToString:@"__NSCFBoolean"]) {
    
                    pair.value = TSNNSCFBooleanToBooleanStringConvertor(pair.value);
                }
    
                [mutablePairs addObject:[pair URLEncodedStringValueWithEncoding:stringEncoding]];
            }
    
            return [mutablePairs componentsJoinedByString:@"&"];
        }
    
        NSString* TSNNSCFBooleanToBooleanStringConvertor(NSNumber* booleanInNSNumber) {
    
            return [booleanInNSNumber boolValue] ? @"true" : @"false";
        }
    

    Also remember to copy the other methods/objects and rename them otherwise it will collide when being linked.

    The new subclass has to be registered with the RestKit:

    [RKMIMETypeSerialization unregisterClass:[RKURLEncodedSerialization class]];
    [RKMIMETypeSerialization registerClass:[TSNRKURLEncodedSerialization class] forMIMEType:RKMIMETypeFormURLEncoded];
    

    UPDATE: This solution works for requests with all methods except GET, HEAD and DELETE. These methods still trigger the original serialisation: not true/false, but 1/0.