A library for loading data from a JSON API datasource. Parses JSON API data into models with support for linking of properties and other resources.
NSDictionary *json = [self responseFromAPIRequest];
JSONAPI *jsonAPI = [JSONAPI jsonAPIWithDictionary:json];
ArticleResource *article = jsonAPI.resource;
NSLog(@"Title: %@", article.title);
For some full examples on how to use everything, please see the tests - https://github.com/joshdholtz/jsonapi-ios/blob/master/Project/JSONAPITests/JSONAPITests.m
Version | Changes |
---|---|
1.0.7 | Added meta and setMeta to JSONAPIResource and JSONAPIResourceBase (joshdholtz#43). |
1.0.6 | Improved resource parsing and added parsing of selfLinks (joshdholtz#35). Thanks to [ artcom](https://github.com/ artcom) for helping! Also removed the need to define setIdProperty and setSelfLinkProperty in every resource (automatically mapped in the init of JSONAPIResourceDescriptor ) |
1.0.5 | Fix 1-to-many relationships serialization according to JSON API v1.0 (joshdholtz#34). Thanks to RafaelKayumov for helping! |
1.0.4 | Add support for empty to-one relationship according to JSON API v1.0 (joshdholtz#33). Thanks to RafaelKayumov for helping! |
1.0.3 | Add ability to map different types of objects (joshdholtz#32). Thanks to ealeksandrov for helping! |
1.0.2 | Just some bug fixes. Thanks to christianklotz for helping again! |
1.0.1 | Now safely checks for NSNull in the parsed JSON. Thanks to christianklotz for that fix! |
1.0.0 | We did it team! We are at the JSON API 1.0 final spec. Resources now use JSONAPIResourceDescriptor for more explicit definitions. HUGE thanks to jkarmstr for doing all the dirty work. Also thanks to edopelawi , BenjaminDigeon, and christianklotz for some bug fixes! |
1.0.0-rc1 | Rewrote core of JSONAPI and JSONAPIResource and all unit tests to be up to spec with JSON API spec 1.0.0-rc3. Removed JSONAPIResourceLinker . Added JSONAPIErrorResource |
0.2.0 | Added NSCopying and NSCoded to JSONAPIResource ; Added JSONAPIResourceFormatter to format values before getting mapped - more info |
0.1.2 | JSONAPIResource IDs can either be numbers or strings (thanks danylhebreux); JSONAPIResource subclass can have mappings defined to set JSON values into properties automatically - more info |
0.1.1 | Fixed linked resources with links so they actually link to other linked resources |
0.1.0 | Initial release |
- Allows resource types to be created into subclasses of
JSONAPIResource
- Set mapping for
JSONAPIResource
subclass to set JSON values and relationships into properties
Clone the repository and drop in the .h and .m files from the "Classes" directory into your project.
JSONAPI is available through CocoaPods, to install it simply add the following line to your Podfile:
pod 'JSONAPI', '~> 1.0.7'
For some full examples on how to use everything, please see the tests - https://github.com/joshdholtz/jsonapi-ios/blob/master/Project/JSONAPITests/JSONAPITests.m
JSONAPI
parses and validates a JSON API document into a usable object. This object holds the response as an NSDictionary but provides methods to accomdate the JSON API format such as meta
, errors
, linked
, resources
, and includedResources
.
Protocol of an object that is available for JSON API serialization. When developing model classes for use with JSON-API, it is suggested that classes be derived from JSONAPIResourceBase
, but that is not required. An existing model class can be adapted for JSON-API by implementing this protocol.
JSONAPIResourceBase
is an object (that gets subclassed) that holds data for each resource in a JSON API document. This objects holds the "id" as ID
and link for self as selfLink
as well as attributes and relationships defined by descriptors (see below)
+ (JSONAPIResourceDescriptor*)descriptor
should be overwritten to define descriptors for mapping of JSON keys and relationships into properties of a subclassed JSONAPIResource.
NSDictionary *json = [self responseFromAPIRequest];
JSONAPI *jsonAPI = [JSONAPI jsonAPIWithDictionary:json];
ArticleResource *article = jsonAPI.resource;
NSLog(@"Title: %@", article.title);
NSLog(@"Author: %@ %@", article.author.firstName, article.author.lastName);
NSLog(@"Comment Count: %ld", article.comments.count);
@interface ArticleResource : JSONAPIResourceBase
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) PeopleResource *author;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, strong) NSArray *comments;
@end
@implementation ArticleResource
static JSONAPIResourceDescriptor *__descriptor = nil;
+ (JSONAPIResourceDescriptor*)descriptor {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__descriptor = [[JSONAPIResourceDescriptor alloc] initWithClass:[self class] forLinkedType:@"articles"];
[__descriptor addProperty:@"title"];
[__descriptor addProperty:@"date"
withDescription:[[JSONAPIPropertyDescriptor alloc] initWithJsonName:@"date" withFormat:[NSDateFormatter RFC3339DateFormatter]]];
[__descriptor hasOne:[PeopleResource class] withName:@"author"];
[__descriptor hasMany:[CommentResource class] withName:@"comments"];
});
return __descriptor;
}
@end
@interface PeopleResource : JSONAPIResourceBase
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *twitter;
@end
@implementation PeopleResource
static JSONAPIResourceDescriptor *__descriptor = nil;
+ (JSONAPIResourceDescriptor*)descriptor {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__descriptor = [[JSONAPIResourceDescriptor alloc] initWithClass:[self class] forLinkedType:@"people"];
[__descriptor addProperty:@"firstName" withDescription:[[JSONAPIPropertyDescriptor alloc] initWithJsonName:@"first-name"]];
[__descriptor addProperty:@"lastName" withJsonName:@"last-name"];
[__descriptor addProperty:@"twitter"];
});
return __descriptor;
}
@end
@interface CommentResource : JSONAPIResourceBase
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) PeopleResource *author;
@end
@implementation CommentResource
static JSONAPIResourceDescriptor *__descriptor = nil;
+ (JSONAPIResourceDescriptor*)descriptor {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__descriptor = [[JSONAPIResourceDescriptor alloc] initWithClass:[self class] forLinkedType:@"comments"];
[__descriptor addProperty:@"text" withJsonName:@"body"];
[__descriptor hasOne:[PeopleResource class] withName:@"author"];
});
return __descriptor;
}
@end
Sometimes you may have parts of a resource that need to get mapped to something more specific than just an NSDictionary
. Below is an example on how to map an NSDictionary
to non-JSONAPIResource models.
We are essentially creating a property descriptor that maps to a private property on the resource. We then override that properties setter and do our custom mapping there.
"attributes":{
"title": "Something something blah blah blah"
"image": {
"large": "http://someimageurl.com/large",
"medium": "http://someimageurl.com/medium",
"small": "http://someimageurl.com/small"
}
}
@interface ArticleResource : JSONAPIResourceBase
@property (nonatomic, strong) NSString *title;
// The properties we are pulling out of a a "images" dictionary
@property (nonatomic, storng) NSString *largeImageUrl;
@property (nonatomic, storng) NSString *mediumImageUrl;
@property (nonatomic, storng) NSString *smallImageUrl;
@end
@interface ArticleResource()
// Private variable used to store raw NSDictionary
// We will override the setter and set our custom properties there
@property (nonatomic, strong) NSDictionary *rawImage;
@end
@implementation ArticleResource
static JSONAPIResourceDescriptor *__descriptor = nil;
+ (JSONAPIResourceDescriptor*)descriptor {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__descriptor = [[JSONAPIResourceDescriptor alloc] initWithClass:[self class] forLinkedType:@"articles"];
[__descriptor addProperty:@"title"];
[__descriptor addProperty:@"rawImage" withDescription:[[JSONAPIPropertyDescriptor alloc] initWithJsonName:@"image"]];
});
return __descriptor;
}
- (void)setRawImage:(NSDictionary*)rawImage {
_rawImage = rawImage;
// Pulling the large, medium, and small urls out when
// this property gets set by the JSON API parser
_largeImageUrl = _rawImage[@"large"];
_mediumImageUrl = _rawImage[@"medium"];
_smallImageUrl = _rawImage[@"small"];
}
@end
Josh Holtz, [email protected], @joshdholtz
JSONAPI is available under the MIT license. See the LICENSE file for more info.