Magical Data Modelling Framework for JSON
Version 1.1.2
NB: Instant performs in a different way under the bonnet than Objective-C. Therefore I can't discover a way to re-create JSONModel in Instant. JSONModel in Objective-C performs in Instant applications through CocoaPods or as an brought in Objective-C collection.
If you like JSONModel and use it, could you please:
- star this repo
- send me some reviews. Thanks!
JSONModel is a library, which allows rapid creation of smart data models. You can use it in your iOS or OSX apps.
JSONModel automatically introspects your model classes and the structure of your JSON input and reduces drastically the amount of code you have to write.
Adding JSONModel to your project
Requirements
ARC only; iOS 5.0+ / OSX 10.7+
SystemConfiguration.framework
Get it as: 1) resource files
- Download JsonModel repositry as a zip file.
- Copy the JSONModel sub-folder into your Xcode project
- Link your app to SystemConfiguration.framework
or 2) via Chocolate pods
- In your venture's Podfile add the JSONModel pod:
pod 'JSONModel'
Resource rule documentation
- The source rule contains category documents, which you can build yourself and transfer into Xcode:
- If you don't already have appledoc set up, set up it with home produce by writing produce set up appledoc.
- Install the certification into Xcode by writing appledoc . in the main listing of the database.
- Restart Xcode if it's already running.
Primary usage
Consider you have a JSON like this:
{"id":"10", "country":"Germany", "dialCode": 49, "isInEurope":true}
- Create a new Objective-C category for your information design and ensure it is acquire the JSONModel category.
- Declare qualities in your headlines information file with the name of the JSON keys:
#import "JSONModel.h"
@interface CountryModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* dialCode;
@property (assign, nonatomic) BOOL isInEurope;
@end
There's no need to do anything in the .m file.
- Initialize your model with data:
#import "CountryModel.h"
...
NSString* json = (fetch here JSON from Internet) ...
NSError* err = nil;
CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];
If the approval of the JSON goes you have all the corresponding qualities in your design booming from the JSON. JSONModel will also try to turn as much information to the kinds you anticipate, in the example above it will:
- convert "id" from sequence (in the JSON) to an int for your class
- just duplicate nation's value
- convert dialCode from variety (in the JSON) to an NSString value
- finally turn isInEurope to a BOOL for your BOOL property
- And thankfully all you had to do is determine the qualities and their predicted kinds.
Examples
Automatic name based mapping
{ "id": "123", "name": "Product name", "price": 12.95 } | @interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString* name; @property (assign, nonatomic) float price; @end @implementation ProductModel @end |
Model cascading (models including other models)
{ "order_id": 104, "total_price": 13.45, "product" : { "id": "123", "name": "Product name", "price": 12.95 } } | @interface OrderModel : JSONModel @property (assign, nonatomic) int order_id; @property (assign, nonatomic) float total_price; @property (strong, nonatomic) ProductModel* product; @end @implementation OrderModel @end |
Model collections
{ "order_id": 104, "total_price": 103.45, "products" : [ { "id": "123", "name": "Product #1", "price": 12.95 }, { "id": "137", "name": "Product #2", "price": 82.95 } ] } | @protocol ProductModel @end @interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString* name; @property (assign, nonatomic) float price; @end @implementation ProductModel @end @interface OrderModel : JSONModel @property (assign, nonatomic) int order_id; @property (assign, nonatomic) float total_price; @property (strong, nonatomic) NSArray<ProductModel>* products; @end @implementation OrderModel @end |
Key mapping
{ "order_id": 104, "order_details" : [ { "name": "Product#1", "price": { "usd": 12.95 } } ] } | @interface OrderModel : JSONModel @property (assign, nonatomic) int id; @property (assign, nonatomic) float price; @property (strong, nonatomic) NSString* productName; @end @implementation OrderModel +(JSONKeyMapper*)keyMapper { return [[JSONKeyMapper alloc] initWithDictionary:@{ @"order_id": @"id", @"order_details.name": @"productName", @"order_details.price.usd": @"price" }]; } @end |
Global key mapping (applies to all models in your app)
[JSONModel setGlobalKeyMapper:[ [JSONKeyMapper alloc] initWithDictionary:@{ @"item_id":@"ID", @"item.name": @"itemName" }] ]; |
Map automatically under_score case to camelCase
{ "order_id": 104, "order_product" : @"Product#1", "order_price" : 12.95 } | @interface OrderModel : JSONModel @property (assign, nonatomic) int orderId; @property (assign, nonatomic) float orderPrice; @property (strong, nonatomic) NSString* orderProduct; @end @implementation OrderModel +(JSONKeyMapper*)keyMapper { return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase]; } @end |
Optional properties (i.e. can be missing or null)
{ "id": "123", "name": null, "price": 12.95 } | @interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString<Optional>* name; @property (assign, nonatomic) float price; @property (strong, nonatomic) NSNumber<Optional>* uuid; @end @implementation ProductModel @end |
Ignored properties (i.e. JSONModel completely ignores them)
{ "id": "123", "name": null } | @interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString<Ignore>* customProperty; @end @implementation ProductModel @end |
Make all model properties optional (avoid if possible)
@implementation ProductModel +(BOOL)propertyIsOptional:(NSString*)propertyName { return YES; } @end |
Lazy convert collection items from dictionaries to models
{ "order_id": 104, "total_price": 103.45, "products" : [ { "id": "123", "name": "Product #1", "price": 12.95 }, { "id": "137", "name": "Product #2", "price": 82.95 } ] } | @protocol ProductModel @end @interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString* name; @property (assign, nonatomic) float price; @end @implementation ProductModel @end @interface OrderModel : JSONModel @property (assign, nonatomic) int order_id; @property (assign, nonatomic) float total_price; @property (strong, nonatomic) NSArray<ProductModel, ConvertOnDemand>* products; @end @implementation OrderModel @end |
Using the built-in thin HTTP client
//add extra headers
[[JSONHTTPClient requestHeaders] setValue:@"MySecret" forKey:@"AuthorizationToken"];
//make post, get requests
[JSONHTTPClient postJSONFromURLWithString:@"http://mydomain.com/api"
params:@{@"postParam1":@"value1"}
completion:^(id json, JSONModelError *err) {
//check err, process json ...
}];
Export model to NSDictionary or to JSON text
ProductModel* pm = [[ProductModel alloc] initWithString:jsonString error:nil];
pm.name = @"Changed Name";
//convert to dictionary
NSDictionary* dict = [pm toDictionary];
//convert to text
NSString* string = [pm toJSONString];
Custom data transformers
@implementation JSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end
Custom handling for specific properties
@interface ProductModel : JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString* name; @property (assign, nonatomic) float price; @property (strong, nonatomic) NSLocale *locale; @end @implementation ProductModel // Convert and assign the locale property - (void)setLocaleWithNSString:(NSString*)string { self.locale = [NSLocale localeWithLocaleIdentifier:string]; } - (NSString *)JSONObjectForLocale { return self.locale.localeIdentifier; } @end
Emoticon Emoticon