Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Magical Data Modelling Framework for JSON

Version 1.2.0

#####NB: Swift works in a different way under the hood than Objective-C. Therefore I can't find a way to re-create JSONModel in Swift. JSONModel in Objective-C works in Swift apps through CocoaPods or as an imported Objective-C library.


If you like JSONModel and use it, could you please:

  • star this repo

  • send me some feedback. Thanks!


JSONModel for iOS and OSX

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) source files

  1. Download the JSONModel repository as a zip file or clone it
  2. Copy the JSONModel sub-folder into your Xcode project
  3. Link your app to SystemConfiguration.framework

or 2) via Cocoa pods

In your project's Podfile add the JSONModel pod:

pod'JSONModel'

If you want to read more about CocoaPods, have a look at this short tutorial.

or 3) via Carthage

In your project's Cartfile add the JSONModel:

github"icanzilb/JSONModel"

Source code documentation

The source code includes class docs, which you can build yourself and import into Xcode:

  1. If you don't already have appledoc installed, install it with homebrew by typing brew install appledoc.
  2. Install the documentation into Xcode by typing appledoc . in the root directory of the repository.
  3. Restart Xcode if it's already running.

Basic usage

Consider you have a JSON like this:

{"id":"10","country":"Germany","dialCode": 49,"isInEurope":true}
  • Create a new Objective-C class for your data model and make it inherit the JSONModel class.
  • Declare properties in your header file with the name of the JSON keys:
#import"JSONModel.h"@interfaceCountryModel : JSONModel@property (assign, nonatomic) intid;
@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 validation of the JSON passes you have all the corresponding properties in your model populated from the JSON. JSONModel will also try to convert as much data to the types you expect, in the example above it will:

  • convert "id" from string (in the JSON) to an int for your class
  • just copy country's value
  • convert dialCode from number (in the JSON) to an NSString value
  • finally convert isInEurope to a BOOL for your BOOL property

And the good news is all you had to do is define the properties and their expected types.


Online tutorials

Official website: http://www.jsonmodel.com

Class docs online: http://jsonmodel.com/docs/

Step-by-step tutorials:


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

Note: the angle brackets after NSArray contain a protocol. This is not the same as the new Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

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 dictionaryNSDictionary* dict = [pm toDictionary];
//convert to textNSString* string = [pm toJSONString];

Custom data transformers

@implementationJSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end

Custom handling for specific properties

@interfaceProductModel : JSONModel@property (assign, nonatomic) intid;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end@implementationProductModel// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocalelocaleWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
  • json validation
  • error handling
  • custom data validation
  • automatic compare and equality features
  • and more.

Misc

Author: Marin Todorov

Contributors: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z. Also everyone who did successful pull requests.

Change log : https://github.com/icanzilb/JSONModel/blob/master/Changelog.md

Utility to generate JSONModel classes from JSON data: https://github.com/dofork/json2object


License

This code is distributed under the terms and conditions of the MIT license.


Contribution guidelines

NB! If you are fixing a bug you discovered, please add also a unit test so I know how exactly to reproduce the bug before merging.

About

Magical Data Modelling Framework for JSON. Create rapidly powerful, atomic and smart data model classes

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages