Giter VIP home page Giter VIP logo

jastor's Introduction

Jastor

Jastor is not maintained anymore. No worries, there are some really good alternatives: JSONModel or Mantle

Jastor is an Objective-C base class that is initialized with a dictionary (probably from your JSON response), and assigns dictionary values to all its (derived class's) typed @properties.

It supports nested types, arrays, NSString, NSNumber, NSDate and more.

Jastor is NOT a JSON parser. For that, you have JSONKit, yajl and many others.

The name sounds like JSON to Objecter. Or something.

Upgrade from previous version:

Add dealloc mehtods to your models and nillify your peoperties. Automattic dealloc is no longer done by Jastor.

Support

Need help with getting Jastor up and running? Got a time-consuming problem you want to get solved quickly?
Get Jastor support on CodersClan.

Examples

You have the following JSON:

{
	"name": "Foo",
	"amount": 13
}

and the following class:

@interface Product
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSNumber *amount;
@end

@implementation Product
@synthesize name, amount;

- (void)dealloc {
	self.name = nil;
	self.amount = nil;
	
	[super dealloc];
}
@end

with Jastor, you can just inherit from Jastor class, and use initWithDictionary:

// Product.h
@interface Product : Jastor
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSNumber *amount;
@end

// Product.m
@implementation Product
@synthesize name, amount;

- (void)dealloc {
	self.name = nil;
	self.amount = nil;
	
	[super dealloc];
}
@end

// Some other code
NSDictionary *dictionary = /* parse the JSON response to a dictionary */;
Product *product = [[Product alloc] initWithDictionary:dictionary];

// Log
product.name // => Foo
product.amount // => 13

Nested Objects

Jastor also converts nested objects to their destination type:

// JSON
{
	"name": "Foo",
	"category": {
		"name": "Bar Category"
	}
}
// ProductCategory.h
@interface ProductCategory : Jastor
@property (nonatomic, copy) NSString *name;
@end

// ProductCategory.m
@implementation ProductCategory
@synthesize name;

- (void)dealloc {
	self.name = nil;
	
	[super dealloc];
}
@end

// Product.h
@interface Product : Jastor
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) ProductCategory *category;
@end

// Product.m
@implementation Product
@synthesize name, category;

- (void)dealloc {
	self.name = nil;
	self.category = nil;
	
	[super dealloc];
}
@end


// Code
NSDictionary *dictionary = /* parse the JSON response to a dictionary */;
Product *product = [[Product alloc] initWithDictionary:dictionary];

// Log
product.name // => Foo
product.category // => <ProductCategory>
product.category.name // => Bar Category

Arrays

Having fun so far?

Jastor also supports arrays of a certain type:

// JSON
{
	"name": "Foo",
	"categories": [
		{ "name": "Bar Category 1" },
		{ "name": "Bar Category 2" },
		{ "name": "Bar Category 3" }
	]
}
// ProductCategory.h
@interface ProductCategory : Jastor
@property (nonatomic, copy) NSString *name;
@end

// ProductCategory.m
@implementation ProductCategory
@synthesize name;

- (void)dealloc {
	self.name = nil;
	
	[super dealloc];
}
@end

// Product.h
@interface Product : Jastor
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSArray *categories;
@end

// Product.m
@implementation Product
@synthesize name, categories;

+ (Class)categories_class {
	return [ProductCategory class];
}

- (void)dealloc {
	self.name = nil;
	self.categories = nil;
	
	[super dealloc];
}
@end


// Code
NSDictionary *dictionary = /* parse the JSON response to a dictionary */;
Product *product = [[Product alloc] initWithDictionary:dictionary];

// Log
product.name // => Foo
product.categories // => <NSArray>
[product.categories count] // => 3
[product.categories objectAtIndex:1] // => <ProductCategory>
[[product.categories objectAtIndex:1] name] // => Bar Category 2

Notice the declaration of

+ (Class)categories_class {
	return [ProductCategory class];
}

it tells Jastor what class of items the array holds.

Nested + Arrays = Trees

Jastor can handle trees of data:

// JSON
{
	"name": "1",
	"children": [
		{ "name": "1.1" },
		{ "name": "1.2",
		  children: [
			{ "name": "1.2.1",
			  children: [
				{ "name": "1.2.1.1" },
				{ "name": "1.2.1.2" },
			  ]
			},
			{ "name": "1.2.2" },
		  ]
		},
		{ "name": "1.3" }
	]
}
// ProductCategory.h
@interface ProductCategory : Jastor
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSArray *children;
@end

// ProductCategory.m
@implementation ProductCategory
@synthesize name, children;

+ (Class)children_class {
	return [ProductCategory class];
}

- (void)dealloc {
	self.name = nil;
	self.children = nil;
	
	[super dealloc];
}
@end


// Code
NSDictionary *dictionary = /* parse the JSON response to a dictionary */;
ProductCategory *category = [[ProductCategory alloc] initWithDictionary:dictionary];

// Log
category.name // => 1
category.children // => <NSArray>
[category.children count] // => 3
[category.children objectAtIndex:1] // => <ProductCategory>
[[category.categories objectAtIndex:1] name] // => 1.2

[[[category.children objectAtIndex:1] children] objectAtIndex:0] // => <ProductCategory>
[[[[category.children objectAtIndex:1] children] objectAtIndex:0] name] // => 1.2.1.2

Custom mapping

If you are receiving a json from a web server:

{
	"first_name": "John",
	"last_name": "Doe"
}
// Person.h
@interface Person : Jastor
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@end

// Person.m
@implementation Person
@synthesize firstName, lastName;

- (void)dealloc {
	[firstName release]; firstName = nil;
	[lastName release]; lastName = nil;

	[super dealloc];
}

- (NSDictionary *)map{
    NSMutableDictionary *map = [NSMutableDictionary dictionaryWithDictionary:[super map]];
    [map setObject:@"first_name" forKey:@"firstName"];
    [map setObject:@"last_name" forKey:@"lastName"];
    return [NSDictionary dictionaryWithDictionary:map];
}

@end

// Code
NSDictionary *dictionary = /* parse the JSON response to a dictionary */;
Person *person = [[Person alloc] initWithDictionary:dictionary];

// Log
person.firstName // => John
person.lastName // => Doe

How does it work?

Runtime API. The class's properties are read in runtime and assigns all values from dictionary to these properties with NSObject setValue:forKey:. For Dictionaries, Jastor instantiates a new class, based on the property type, and issues another initWithDictionary. Arrays are only a list of items such as strings (which are not converted) or dictionaries (which are treated the same as other dictionaries).

Installation

Just copy Jastor.m+.h and JastorRuntimeHelper.m+.h to your project, create a class, inherit, use the initWithDictionary and enjoy!

Testing

Make sure to initialize git submodules.

git submodules init
git submodules update

In Xcode, hit CMD+U under iPhone simulator scheme.

REALLY Good to know

What about properties that are reserved words?

As for now, id is converted to objectId automatically. Maybe someday Jastor will have ability to map server and obj-c fields.

Jastor classes also conforms to NSCoding protocol

So you get initWithCoder/encodeWithCoder for free.

You can look at the tests for real samples.

Alternatives

Contributors

jastor's People

Contributors

elado avatar erlichmen avatar snappedtogrid avatar yosit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jastor's Issues

Infinit loop under iOS 8 (beta 5 atm)

Hello,

For some reason, class_copyPropertyList() - used in the JastorRuntimeHelper/propertyNames: method - now returns additional keys such as 'hash', 'superclass', 'debugDescription' and... 'description'.
That last key seems to interfere with the Jastor's description method and results in infinit loops.

That quick and dirty fix made it works for me (in the propertyNames: method of JastorRuntimeHelper.m) :

NSString *string = [NSString stringWithUTF8String:name];
if(![string isEqualToString:@"description"] && ![string isEqualToString:@"superclass"] && ![string isEqualToString:@"hash"] && ![string isEqualToString:@"debugDescription"])
[propertyNamesArray addObject:string];

Missing LICENSE file for Cocoapods

An infinitesimal issue with the CocoaPods build:
[!] Unable to read the license file .../Pods/jastor/LICENSE for the spec jastor (0.1.0)

Would be nice if it got added so CocoaPods would stop complaining :-).

Thanks!

Capitalised JSON

I'm currently having to map every property as the JSON I'm connecting to has capitalised property names such as

{
Prop1 : value
}

It would be great if jastor could handle this automatically or allow me to set a property to handle this.

support for inheritance?

Any plan to support for inheritance?

ProductCommon : jastor
{
commonAttributes;
}

Product1 : ProductCommon
{
product1_specific;
}

Product2 : ProductCommon
{
product2_specific;
}

List json

Dear friend,
Help me create class object for below json:
{
{
"name": "Foo",
"amount": 13
},
{
"name": "Foo",
"amount": 13
}
}

CocoaPods Version Out Dated?

Hi guys,

Thanks for a great library. I'm using Jastor via CocoaPods (pod 'Jastor') however the version thats pulled down (I believe from tag 0.2.1) doesn't include the 'map' method that was added 4 months ago. Can you possibly tag and update the PodSpec (assume the code is in an appropriate state for release)?

Thanks in advance.

Add option to retail nil attributes.

Is there anyway you could add an option somewhere so that nil attributes are converted to JSON keys with the value null? This would be great for the case when a missing key is not semantically equivalent to a null value for an object.

If you want to point me in the right direction I can try to do this myself. I saw several if attr == nil comparisons, but I'm not sure what else they are doing. Thanks!

Performance issue of map

I'm using Jastor for some large JSON and noticed processing was not so fast. It seems as [self map] is called a very large number of times inside initWithDictionary. Why not move the call out of the main loop?

Unrecognized selector sent to instance error

I have a custom class ResponseIdSearch : Response (Response obviously extends Jastor and defines several string and int vars) that is getting an unrecognized selector error sent to it when an Array of complex objects.

ResponseIdSearch *salesResponse = [[ResponseIdSearch alloc] initWithDictionary:dictionaryFromJSON];

The line it fails on is Jastor.m:43

Class arrayItemType = [[self class] performSelector:NSSelectorFromString([NSString stringWithFormat:@"%@_class", key])];

which results in

2013-06-06 13:32:14.067 MyApp[55784:c07] +[ResponseIdSearch sales_class]: unrecognized selector sent to class 0x53db38

Where "sales" is the key in the Dictionary and there are 7 elements to the array.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.