TypedJSON 1.2.0

TypedJSON 1.2.0

Maintained by tonyzp.

TypedJSON 1.2.0

  • By
  • tp


CI Status Version License Platform

The way we handle Objective-C JSON dictionary is Ugly.

Objective-C is a runtime, weakly typed language. The NSDictionary class in Objective-C isn't a type-safe object.

Suppose we have a json dictionary:

NSDictionary *json = @{ @"username": @"tp", @"password": @"123456", @"scores": @{ @"programming": @70, @"language": @80 }, @"tels": @[ @"1367890876", @"02884435261" ] };

We may access the dictionary in this way:

NSString *username = json[@"username"];

if (!username || ![username isKindOfClass:NSString.class] || username.length == 0) {

// Do something with username string


NSDictionary *scores = json[@"scores"];

if (!scores || ![scores isKindOfClass:NSDictionary.class] || scores.count == 0) {

NSNumber *score = scores[@"programming"];

if (!score || ![score isKindOfClass:NSNumber.class]) {

// Do something with programming score number

The problem here is, we do much things with type & value check to insure type-safety, these make our code ugly.

A better way to handle this

With TypedJSON, we use chain operators to solve this problem in a semantic way. These try to insure the elegance and readability of the code.

NSString *username = json.tj.string(@"username").without.empty.value;

if (!username) {

// Do something with username string


NSNumber *score = json.tj.dictionary(@"scores").number(@"programming").value;

if (!score) {

// Do something with programming score number

More example

The json data in this example:

    "username": "tp",
    "password": "123456",
    "scores": {
        "programming": 70,
        "language": 80
    "tels": [

How we access this json dictionary with TypedJSON:

NSDictionary *json = [self loadJSON];
// Get username from json exclued empty string value '', return 'anonymous' while nil.
NSString *username = json.tj.string(@"username").without.empty.defaults(@"anonymous").value;
// Get programming score number in scores dictionary from json.
NSNumber *programmingScore = json.tj.dictionary(@"scores").number(@"programming").value;
// Get politics score number in scores dictionary from json, return 0 while politics do not exists.
NSNumber *politicsScore = json.tj.dictionary(@"scores").number(@"politics").with.defaults(@0).value;
NSLog(@"The programming score of %@ is %@, and politics %@.", username, programmingScore, politicsScore);


TypedJSON is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'TypedJSON'

Then run pod install to integrate.


To import TypedJSON, you just:

#import <TypedJSON/TypedJSON.h>

Read value in dictionary with type safety

Read string in dictionary with a specified key:


The value could be nil while it's not a NSString type.

Read number in dictionary with a specified key:


The value could be nil while it's not a NSNumber type.

Read array in dictionary with a specified key:


The value could be nil while it's not a NSArray type.

Read dictionary in dictionary with a specified key:


The value could be nil while it's not a NSDictionary type.

Insure not empty

Sometimes we get empty value in ditionary, such as:

  • empty string: ""
  • empty array: @[]
  • empty dictionary: @{}

Use - empty operator to ignore them:


Return nil if the value of "foo" is a ""


Return nil if the value of "foo" is a @[]


Return nil if the value of "foo" is a @{}

Provide default value while get nil

Suppose we get nil value in the chain, and we need to provide a default value:


The - with operator could be omitted, it just to insure semantics of the statment.

The - any operator

This operator just get value by a specified key, without type check:


The return value is an id type.

Or you could use Valuable extension to do the type check:


- stringValue will make sure the return value matches NSString type, if not then return nil.

Access values in a chain

Supporse the value is wrapped in the inner dictionary:

    "foo": {
        "bar": {
            "greeting": "Hello ~"

We can access the greeting in a chain:


The - find operator

In the example above we access greeting in an operator chain, with - find operator we can change the code:


- find operator enumerate the dictionary recursively to get the value mathes the specified key, but doesn't do the type check. In order to insure type-safety, we could use Valuable extension method - stringValue:


The - as operator

This operator is similar to Valuable extension methods. It make sure the value matches the specified class type. Usually we use this operator after - find or - any operators in the operator chain:


This make sure the result value of - find operator @"greeting" matches NSString class.

It''s equal to:


Error case

If the json object is nil or not a subcalss of NSDictionary, use .tj directly may cause crash. So we should make nullability & type check for json object before access with tj. Or we can access with TJ(json) macro to do this for you.

// The `json` object could be `nil`, or it's class is NOT a kind of NSDicionary.
NSString *username = TJ(json).string(@"username").without.empty.defaults(@"anonymous").value;


tp, [email protected]


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