Code Monkey home page Code Monkey logo

llmodel's Introduction

LLModel: Object Property Mapper for JSON

LLModel is a library for mapping the JSON data to object properties. It works perfectly well alongside with AFNetwoking.

LLModel:

  • supports recursive model initializations (see examples below)
  • supports primitive values such as bool, char, integer, float and others
  • handles NULL values gracefully
  • handles Date and URL values without any problem

Version 1.1

  • added default *(NSString )description method implementation.
  • iOS7 compatibility

Example usage

Say you have the following three models:

  • User
  • Address
  • Feed

And the JSON data we will be receiving is going to be User which contains one Address and many Feeds.

Here I will show only the User model (download the example to see other models). First of all, you have to subclass LLModel.

@interface User : LLModel
@property (strong, nonatomic) NSNumber *userId;
@property (strong, nonatomic) NSString *firstName;
@property (strong, nonatomic) NSString *lastName;
@property (strong, nonatomic) NSString *username;
@property (nonatomic) BOOL publicProfile;
@property (nonatomic) NSInteger loginCount;
@property (strong, nonatomic) NSDate *createdAt;
@property (strong, nonatomic) Address *address;
@property (strong, nonatomic) NSMutableArray *feeds;
@end

In the implementation file, you need to override the initWithJSON:(id)JSON method and define your mapping. Mapping is very basic,

  • The left side (dictionary keys) is your property names.
  • The right side (dictionary values) is the JSON keys.

There is no need to worry about the types, LLModel will check the property types at runtime and assign the values accordingly.

@implementation User

- (id)initWithJSON:(id)JSON
{
    self = [super initWithJSON:JSON];
    if(self) {

        self.mappingDateFormatter = [[NSDateFormatter alloc] init];
        [self.mappingDateFormatter setDateFormat:@"dd.MM.yyyy"];
        
        NSDictionary *mapping = @{@"userId":@"id",
                                  @"firstName":@"first_name",
                                  @"lastName":@"last_name",
                                  @"username":@"username",
                                  @"publicProfile":@"public_profile",
                                  @"loginCount":@"login_count",
                                  @"createdAt":@"created_at"
                                  @"address":@"address",
                                  @"feeds":@{@"key":@"feeds",@"type":@"Feed"}};
        
        [self setValuesWithMapping:mapping andJSON:JSON];
        
        // check if there are any errors
        if(self.mappingErrors.count > 0) {
            [self logAllMappingErrors];
        }
    }
    return self;
}

@end

And finally, after you make a call to an API, initialize the LLModel instance (User) with the received JSON. That's it!

    // The JSON from the folowing URL is generated specially for this project.
    NSURL *url = [NSURL URLWithString:@"http://www.dailypul.se/api/v1/test/llmodel"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        
        // Simply init the user with JSON, that's all!
        self.user = [[User alloc] initWithJSON:JSON];
        
        Feed *feed = [self.user.feeds objectAtIndex:0];
        
        // Log the model values
        NSLog(@"User description: %@", self.user.description);
        NSLog(@"User Address description: %@", self.user.address.description);
        NSLog(@"User Feed[0] description: %@", feed.description);
        
        NSLog(@"User dictionary: %@", [self.user reverseMapping]);
        NSLog(@"Feed dictionary: %@", [feed reverseMapping]);
        
    } failure:nil];
    [operation start];

Recursive Mapping

In the above example the most interesting part is the mapping of the "address" and "feeds" properties.

LLModel simply gets the values from the JSON and creates an Address object (Address model should also be a subclass of LLModel) and assigns to property.

Feeds are a little bit different story. Since feeds property is defined as NSMutableArray (or it can be NSArray) LLModel can't know which type of objects it must contain.

Therefore, in the mapping, you have to provide a dictionary with the keys: key and type. LLModel will then create the Feed objects and add them to NSarray and finally will assign to the property.

Reverse Mapping

If you want to receive the object values in the form of JSON data, you can simply call the *(NSDictionary )reverseMapping method. Well, if you wonder, reverse mapping is also recursive. In other words, if you call this on a User instance, you will also get Address and Feeds JSON inside the main JSON object.

Error handling

LLModel will add NSerror objects to self.mappingErrors if there are any errors while parsing the JSON. You can log the errors with the helper method [self logAllMappingErrors].

Description (Print all property values)

LLModel has a default implementation for *(NSString )description. This method prints all the properties with their values, so you can easily debug your application.

Best Practice

I recommend creating a BaseModel which will be a subclass of LLModel. All of your models then should subclass BaseModel instead of LLModel directly. One of the main reasons for this approach is because many of the dates you receive from JSON will have the same date format, so in BaseModel you can define the date formatter only once.

Example Project

Please download the example project to see how the entire system works.

Contact

Ömer Faruk Gül

My LinkedIn Account

llmodel's People

Contributors

omergul avatar jeffrey903 avatar

Watchers

 avatar

Forkers

aamershahzad2

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.