I'm trying to load iTunes Search API results into custom objects using RestKit. I've defined a simple NSObject subclass for the results:
@interface LSiTunesResult : NSObject
@property (nonatomic) NSInteger itemID;
@property (nonatomic) NSInteger artistID;
@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *artistName;
@property (strong, nonatomic) NSString *collectionName;
@property (strong, nonatomic) NSString *itemDescription;
@property (strong, nonatomic) NSURL *imageURL;
@property (strong, nonatomic) NSURL *thumbnailURL;
@property (strong, nonatomic) NSURL *trackPreviewURL;
@property (strong, nonatomic) NSURL *trackViewURL;
//
+ (RKObjectMapping *)objectMapping;
@end
For simplicity's sake, I've defined object mapping
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[LSiTunesResult class]];
[mapping addAttributeMappingsFromDictionary:@{
@"artistName" : @"artistName"
}];
I've tried a few different ways to actually request the results, using both a custom RKObjectManager and an RKObjectRequestOperation. My simple example with RKObjectRequestOperation looks like:
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[LSiTunesResult objectMapping] pathPattern:nil keyPath:@"results" statusCodes:nil];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:urlRequest responseDescriptors:@[responseDescriptor]];
[operation.HTTPRequestOperation setAcceptableContentTypes:[NSSet setWithObject:@"text/javascript"]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"The search results are: %@", [mappingResult array]);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failure reason: %@", [error localizedDescription]);
}];
[operation start];
Unfortunately, I get the following error from RKResponseMapperOperation: "restkit.network:RKResponseMapperOperation.m:197 Failed to parse response data: Loaded an unprocessable response (200) with content type 'text/javascript'"
I have RestKit network logging on, and it appears that the response from the iTunes API marks the content type as 'text/javascript', while the body contains valid JSON. I've tried telling the RKObjectRequestOperation that text/javascript is an acceptable content type.
Does anyone have any experience with the iTunes API and RestKit? I'm curious if this is a simple mapping issue on my end, or if the iTunes API claiming the content type is javascript while it appears to be valid JSON is throwing off RestKit. Below is a sample of the iTunes Search API response that is logged during my example.
2012-10-21 01:48:54.061 Listen[99898:617] T restkit.network:RKHTTPRequestOperation.m:124 GET 'http://itunes.apple.com/search?term=The%20Lumineers&country=US&media=music&limit=1' (200):
response.headers={
"Cache-Control" = "no-transform, max-age=60";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Length" = 519;
"Content-Type" = "text/javascript; charset=utf-8";
Date = "Sun, 21 Oct 2012 05:48:54 GMT";
Vary = "Accept-Encoding";
"X-Apple-Partner" = "origin.0";
"apple-timing-app" = "49 ms";
"x-apple-application-instance" = 1018018;
"x-apple-application-site" = NWK;
"x-apple-orig-url-path" = "/search?term=The%20Lumineers&country=US&media=music&limit=1";
"x-apple-translated-wo-url" = "/WebObjects/MZStoreServices.woa/ws/wsSearch?term=The%20Lumineers&country=US&media=music&limit=1";
"x-webobjects-loadaverage" = 0;
}
response.body=
{
"resultCount":1,
"results": [
{"wrapperType":"track", "kind":"music-video", "artistId":350720227, "trackId":516035614, "artistName":"The Lumineers", "trackName":"Ho Hey", "trackCensoredName":"Ho Hey", "artistViewUrl":"https://itunes.apple.com/us/artist/the-lumineers/id350720227?uo=4", "trackViewUrl":"https://itunes.apple.com/us/music-video/ho-hey/id516035614?uo=4", "previewUrl":"http://a404.v.phobos.apple.com/us/r30/Video/fd/81/e1/mzi.gxodlwda..640x256.h264lc.u.p.m4v", "artworkUrl30":"http://a1838.phobos.apple.com/us/r30/Video/v4/41/64/37/416437c2-c02e-4706-3f13-a47f50ec2ccc/Cover.40x30-75.jpg", "artworkUrl60":"http://a621.phobos.apple.com/us/r30/Video/v4/41/64/37/416437c2-c02e-4706-3f13-a47f50ec2ccc/Cover.80x60-75.jpg", "artworkUrl100":"http://a1629.phobos.apple.com/us/r30/Video/v4/41/64/37/416437c2-c02e-4706-3f13-a47f50ec2ccc/Cover.100x100-75.jpg", "collectionPrice":1.99, "trackPrice":1.99, "releaseDate":"2012-04-03T07:00:00Z", "collectionExplicitness":"notExplicit", "trackExplicitness":"notExplicit", "trackTimeMillis":160952.0, "country":"USA", "currency":"USD", "primaryGenreName":"Singer/Songwriter"}]
}
Two things to make this work.
The first one you got:
operation.HTTPRequestOperation.acceptableContentTypes = [NSSet setWithObject:@"text/javascript"];
The second one is to register the json serializer for this type.
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/javascript"];
Then it all works!