Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestKit willMapData:

The following code receives a JSON response from my server, which consists of an array of elements, each having a 'created_at' and an 'updated_at' key. For all of these elements, I want to remove a single character (a colon) in the strings that are set for these two keys.

- (void)objectLoader:(RKObjectLoader*)loader willMapData:(inout id *)mappableData {
    // Convert the ISO 8601 date's colon in the time-zone offset to be easily parsable
    // by Objective-C's NSDateFormatter (which works according to RFC 822).
    // Simply remove the colon (:) that divides the hours from the minutes:
    // 2011-07-13T04:58:56-07:00 --> 2011-07-13T04:58:56-0700 (delete the 22nd char)
    NSArray *dateKeys = [NSArray arrayWithObjects:@"created_at", @"updated_at", nil];
    for(NSMutableDictionary *dict in [NSArray arrayWithArray:(NSArray*)*mappableData])
    for(NSString *dateKey in dateKeys) {
        NSString *ISO8601Value = (NSString*)[dict valueForKey:dateKey];
        NSMutableString *RFC822Value = [[NSMutableString alloc] initWithString:ISO8601Value];
        [RFC822Value deleteCharactersInRange:NSMakeRange(22, 1)];
        [dict setValue:RFC822Value forKey:dateKey];
        [RFC822Value release];
    }
}

However, the line [dict setValue:RFC822Value forKey:dateKey]; raises an NSUnknownKeyException with the message this class is not key value coding-compliant for the key created_at.

What am I doing wrong here? My main issue is maybe that I don't really feel comfortable with this inout declaration...

like image 551
Dennis Avatar asked Jul 15 '26 04:07

Dennis


1 Answers

Your inout declaration looks OK to me. I suggest you to print mappableData with NSLog to see what does it actually look like.

Edit: Based on the discussion in the comments, mappableData in this case is actually a collection of JKDictionary objects. JKDictionary is defined in JSONKit.h (a JSON parsing library that RestKit is using) as a subclass of NSDictionary. Therefore, it's not a mutable dictionary and does not implement [NSMutableDictionary setValue:forKey:]. That's why you're getting NSUnknownKeyException during runtime.

One way to achieve what you want could be something like that (not tested!):

- (void)objectLoader:(RKObjectLoader*)loader willMapData:(inout id *)mappableData {
    // Convert the ISO 8601 date's colon in the time-zone offset to be easily parsable
    // by Objective-C's NSDateFormatter (which works according to RFC 822).
    // Simply remove the colon (:) that divides the hours from the minutes:
    // 2011-07-13T04:58:56-07:00 --> 2011-07-13T04:58:56-0700 (delete the 22nd char)
    NSArray *dateKeys = [NSArray arrayWithObjects:@"created_at", @"updated_at", nil];
    NSMutableArray *reformattedData = [NSMutableArray arrayWithCapacity:[*mappableData count]];

    for(id dict in [NSArray arrayWithArray:(NSArray*)*mappableData]) {
        NSMutableDictionary* newDict = [dict mutableCopy];
        for(NSString *dateKey in dateKeys) {
            NSMutableString *RFC822Value = [[newDict valueForKey:dateKey] mutableCopy];
            [RFC822Value deleteCharactersInRange:NSMakeRange(22, 1)];
            [newDict setValue:RFC822Value forKey:dateKey];
        }
        [reformattedData addObject:newDict];
    }
    *mappableData = reformattedData;
}
like image 169
Victor K. Avatar answered Jul 21 '26 06:07

Victor K.