Coder Social home page Coder Social logo

qingshan2346 / jagpropertyconverter Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jagill/jagpropertyconverter

1.0 1.0 0.0 85 KB

An Objective-C library to convert model objects to PropertyLists/JSON Dictionaries, and vice versa.

License: MIT License

jagpropertyconverter's Introduction

JAGPropertyConverter

JAGPropertyConverter is a library to allow easy serialization/deserialization to/from JSON or PropertyList formats.

Overview

JAGPropertyConverter allows you to convert a JSON dictionary such as

{ 
    "userID" : 1234,
    "name" : "Jane Smith",
    "likes" : ["swimming", "movies", "tennis"],
    "invitedBy" : { 
        "userID" : 9876,
        "name" : "Bob Willis"
    }
}

to/from Objective-C "model" classes such as:

@interface User : NSObject
    @property (assign)  int         userID;
    @property (copy)    NSString    *name;
    @property (strong)  NSArray     *likes;
    @property (strong)  User        *invitedBy;
@end

It does this by using the objc runtime library to discover which properties are defined on an object, and then using Key-Value coding to set/retrieve the values.

It will convert recursively, so a model's dictionary of models with array properties of further models will be handled correctly.

There are three "outputTypes" that the converter supports when converting from a model to an NSDictionary: Full, PropertyList, and JSON.

  • Full output "converts" any unrecognized NSObject subclass to itself. Thus the NSDictionary would have a value of that object.
  • PropertyList output drops any unrecognized NSObject subclass, so that the resultant NSDictionary is PropertyList-compliant. (But see the section on NSURL below)
  • JSON output drops any unrecognized NSObject subclass, so that the resultant NSDictionary is JSON-compliant. (But see the sections on NSURL and NSDate below).

Models

Converterting from a Model to an NSDictionary is relatively straightforward, using the property name as a key and the property value as a value. Converting from an NSDictionary to a model requires an important first step of recognizing what Model class the NSDictionary represents. JAGPropertyConverter has an "identifyDict" block property that checks any NSDictionary value, and if it returns a Class, the converter attempts to convert the NSDictionary into that class. If identifyDict returns nil, the converter leaves the NSDictionary unchanged.

To determine which NSObject subclasses are considered "Models" (i.e., which it should convert), JAGPropertyConverter relies on its shouldConvert: and shouldConvertClass: block properties. Unfortunately we currently need both properties -- hopefully in the future we can just use one block which can handle either classes or NSObjects.

By default, weak/assign object pointers are not converted (but assign properties for scalars are). This is because weak references often indicate a retain loop (eg, between an object and its delegate), which would lead to cycle in the object graph and thence an infinite loop in the conversion. This property can be controlled by the "shouldConvertWeakProperties" in JAGPropertyConverter.

NSURL

NSURL properties are not technically valid for JSON or ProperyLists, so JAGPropertyConverter serializes/deserializes them using the string of the absolute path.

NSDate

NSDate properties are not valid for JSON, and different use cases will call for different serialization methods. We allow for this by the convertToDate and convertFromDate block properties. They are called when converting to/from NSDate properties with JSON output type.

NSObject properties

NSObject itself has some properties. JAGPropertyFinder ignores these. If there is need in the future, JAGPropertyFinder could take a setting determining whether it ignores or finds those properties.

NSSet

JAGPropertyConverter converts arrays to sets and vice-versa, as needed.

Example Usage

//Serialization
MyModel *model = [MyModel populatedModel];
JAGPropertyConverter *converter = [[JAGPropertyConverter alloc] initWithOutputType:kJAGJSONOutput];
converter.shouldConvert = ^(id obj) {
    return [obj isKindOfClass:[MyModel class]];
}
converter.shouldConvertClass = ^(Class aClass) {
    return [aClass isSubclassOfClass:[MyModel class]];
}
NSDictionary *jsonDictionary = [converter convertToDictionary:model];

//Deserialization
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithContentsOfFile:@"/path/to/model.json"];
JAGPropertyConverter *converter = [[JAGPropertyConverter alloc] init];
converter.identifyDict = ^(NSDictionary *dict) {
    if ([dict valueForKey:@"userID"]) {
        return [User class];
    } else if ([dict valueForKey:@"primaryKey"]) {
        return [MyModel class];
    }
    return nil;    
}
MyModel *model = [converter convertPropertyToObject:jsonDictionary];

The converter can also handle arrays and dictionaries as inputs as well.

Things to do

Since JAGPropertyConverter uses Key-Value coding to get/set values, it doesn't respect custom getters and setters with non-standard names. JAGProperty has this ability, so we could in theory support this. Two things have dissuaded us so far. The first is that ARC produces warnings, since you are invoking an unknown (to it) selector to get/set properties, so it can't ensure memory management is handled correctly. The second is that Key-Value coding handles scalars decently well, which would take a little more work to do when directly using the properties getters and setters.

While Key-Value coding handles scalars decently well, we have not yet enabled JAGPropertyConverter to parse them into a JSON-value format.

Requirements

JAGPropertyConverter requires iOS 4.0 or higher, and uses ARC. In theory it should also work with OS X 10.6 or higher, but so far it has only been tested for iOS development.

Credits

JAGPropertyConverter was created by James Gill in the development of SpotNote. The intial code for JAGProperty came from Mike Ash's RTProperty class, in his excellent runtime libraries.

License

JAGPropertyConverter is available under the MIT license. See the LICENSE file for more info.

jagpropertyconverter's People

Contributors

jagill avatar

Stargazers

 avatar

Watchers

 avatar

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.