Search code examples
objective-cgithub-mantle

Using Mantle with Sickbeard API


I'm trying to map the responses from the Sickbeard API to my objects with Mantle, but I can't figure out how, since the response is key-value based using TVDB id's as key, like this:

"data": {
    "71663": {
        "air_by_date": 0, 
        "cache": {
            "banner": 1, 
            "poster": 1
        }, 
        "language": "en", 
        "network": "FOX", 
        "next_ep_airdate": "2014-09-28", 
        "paused": 0, 
        "quality": "Any", 
        "show_name": "The Simpsons", 
        "status": "Continuing", 
        "tvdbid": 71663, 
        "tvrage_id": 6190, 
        "tvrage_name": "The Simpsons"
    }, 
    "72227": {
        "air_by_date": 0, 
        "cache": {
            "banner": 1, 
            "poster": 1
        }, 
        "language": "en", 
        "network": "CBS", 
        "next_ep_airdate": "", 
        "paused": 0, 
        "quality": "Any", 
        "show_name": "Two and a Half Men", 
        "status": "Continuing", 
        "tvdbid": 72227, 
        "tvrage_id": 6454, 
        "tvrage_name": "Two and a Half Men"
    }
}

Since the data object does not simply contain an array of objects like this [{"key": value},{"key": value}] but instead objects keyed by some unique id, I'm not sure how I should map it into my SBShow classes, defined like:

#import <Foundation/Foundation.h>
#import <Mantle.h>

@interface SBShow : MTLModel <MTLJSONSerializing>

@property (nonatomic, strong) NSNumber *tvdbid;
@property (nonatomic, strong) NSString *showName;
@property (nonatomic, strong) NSString *network;
@property (nonatomic, strong) NSString *status;

@end

@implementation SBShow

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{@"showName": @"show_name"};
}

+ (NSValueTransformer *)dateJSONTransformer {

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];

    return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) {
        return [formatter dateFromString:str];
    } reverseBlock:^(NSDate *date) {
        return [formatter stringFromDate:date];
    }];
}

@end

Any help would be greatly appreciated.


Solution

  • You can do it like this, by adding the key to the rest of the 'JSON dictionary':

    NSMutableArray *shows = [NSMutableArray array];
    // data is an NSDictionary, representing the 'data' key in the JSON
    [data enumerateKeysAndObjectsUsingBlock:^(NSString *tvdbID, NSDictionary *showData, BOOL *stop) {
        NSMutableDictionary *modelDictionary = [showData mutableCopy];
        modelDictionary[@"tvdbid"] = tvdbID;
        NSError *error = nil;
        SBShow *show = [MTLJSONAdapter modelOfClass:SBShow.class 
                                 fromJSONDictionary:modelDictionary 
                                              error:&error];
        [shows addObject:show];
    }];
    
    NSLog(@"Show models are %@", shows);
    

    You can write your own transformer to encapsulate this logic and apply it to the data key if appropriate.