Giter Site home page Giter Site logo

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"
    },
    "friends" : [
        { "userID" : 8873, "name" : "Jodi Fischer" },
        { "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;
    @property (strong)  NSSet       *friends;
@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 classesToConvert property. Objects which are subclasses of a Class in classesToConvert are converted.

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.classesToConvert = [NSSet setWithObject:[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 composeModelFromObject:jsonDictionary];

The converter can also handle NSArray, NSSet, and NSDictionary inputs as well. To see an extensive set of code samples, look at JAGPropertyConverterTests/ExampleTest.m .

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 struct (and similar) scalars decently well, we have not yet enabled JAGPropertyConverter to parse them into a JSON-value format.

Known Bugs

JAGPropertyConverter doesn't handle NSOrderedSet, NSCountedSet or custom subclasses of NSArray/NSDictionary very well. You may find them composed into a vanilla NSSet/NSArray/NSDictionary. Support for the less-common Apple-supplied classes can be implemented when it's needed, but custom subclasses would require a bit more work.

Decomposed BOOL properies will serialize under JSONKit to 0s and 1s. This is actually due to a bug in Apple's Key-Value coding. The documentation claims that it converts aBool into [NSNumber numberWithBool:aBool], but in fact it looks like it uses [NSNumber numberWithInt:aBool] or similar. JSONKit (correctly) views this as an integer, not a boolean.

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.

ExampleTest.m uses the literal expressions introduced in Xcode 4.4. Building that particular test requires Xcode 4.4, but all other files (including all files in the library proper) should work for any version of Xcode >4.0.

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. The documentation was generated by appledoc, and the tag versioning follows Semantic Versioning.

License

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

jagpropertyconverter's People

Contributors

jagill avatar lucdion 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

jagpropertyconverter's Issues

convertToDate - handling 2 different date types

If the json object has two date string objects (say, 2013-03-02, 2013-03-02 10:15), can't the convertToDate message handle these formats.

JAGPropertyConverter *converter = [[JAGPropertyConverter alloc] initWithOutputType:kJAGJSONOutput] ;

[converter setConvertToDate:^(id d1)
{
return [NSDate convertFromStringDate:d1 usingFormatterString:DT_yyyy_MM_dd_HH_mm_ss];
} ];

    [converter setConvertToDate:^(id d2)
     {
         return [NSDate convertFromStringDate:d12 usingFormatterString:DT_yyyy_MM_dd];

     }];

I have written a custom method on NSDate to convert different string date formats. What I am seeing is that, I can use only one at any point of time.
Commenting either of the above works fine for the individual date string objects. However if uncomment both of the above, only one gets converted. This lead me to believe that I can convert only one date string object ? Am I missing something. Thanks in advance for your reply.

how to handle nested json?

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

now, key "likes" is a NSArray, if it contains model array but not string value, how to handle it?
how about add another block method like "converter.identifyArray"?
thanks.

Model composed of different Model

Hi,
Is this recursive supposed to address a model composed of different models. In this case dataBlock(see below) is composed of applicationBlock and passwordBlock in addition to the key value pairs. Is this use case applicable for the JAGPropertyConverter project.

dataBlock: {
applicationBlock:
{
majorVersion: "2",
minorVersion: "0",
subVersion: "0",
rcVersion: "16",
environment: "TEVV"
}
,
prefix: "",
suffix: "",
image: "",
pneumonic: "FNLN",
firstName: "First Name",
middleName: "",
lastName: "Last Name",
email: "[email protected]",
tempKey: "ctfdkl7c852d5568960adc854f92d7",
failedLogin: "0",
passwordDate: "2012-08-28",
tempPasswordFlag: "N",
lockedFlag: "N",
activeFlag: "Y",
ersAdminFlag: "0",
speciality: "1",
role: "63",
passwordBlock:
{
pwdMaxBadLogin: "5",
pwdTimeout: "90",
pwdHistoryCount: "10",
pwdNumberCount: "1",
pwdUpperCaseCount: "1",
pwdLowerCaseCount: "1",
pwdSpecialCount: "1",
pwdMinLength: "6",
pwdMaxLength: "16",
pwdNotificationText: "Validation text string.",
systemUserFilter: "5,6"
}

}

JAG Property Converter......

Hi

I am trying to use this "JAG Property Converter" Library but it is giving me too much errors.
I just want to know that where are the steps for this library to be implemented in existing project in IOS.
Did you have given the steps?
I didn't find them in whole readme note.
Please provide the steps so that i can use this for my project.
Reply me please.

Thanks and Regards,
Jittender K Thakur

Converting JSON into NSArray

If my dictionary is a list of objects, how would I convert a dictionary of this type into an NSArray of my objects?

For example [{"Id":1,"Name":"ABC"},{"Id":2,"Name":"DEF"}]

Going into:

@interface Survey : NSObject

@property (assign) int Id;
@property (nonatomic, copy) NSString *Name;

@EnD

Nested Objects

Does this class parse nested objects, for example, if you had a parent object, with child objects, with grand child objects. I couldn't see any examples, maybe I've missed it. Thanks in advance.

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.