TBRJSONMapper is an Objective-C (with Swift support) library for mapping JSON into model data classes while writing as little code as possible.
The main idea is that by following a set of conventions, you do not need to specify what property in the JSON file matches what model object. Doing this can save huge amounts of time during prototyping or if you control both the server API (or other JSON source) and the iOS client.
Accompanying this documentation is a set of examples both in Swift and Objective-C.
To use TBRJSONMapper on your app, simply drag the TBRJSONMapper class files (.m and .h) into your project and import the header where neccessary. If you're using swift, import the header file into your bridging header.
Let's assume you have the following JSON file that you wish to map to Objective-C / iOS classes:
{
"Address" : {
"name" : "John Doe",
"email" : "john@doeind.com",
"partTime" : false,
"Phones" : [
{
"type" : "office",
"number" : "01234 56789"
},
{
"type" : "mobile",
"number" : "0777 9874 321"
},
{
"type" : "home",
"number" : "1124 7153 060"
}
]
}
}
//Address.h
#import <Foundation/Foundation.h>
@interface Address : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *email;
@property (strong, nonatomic) NSNumber *partTime;
// One-to-many relationship
@property (strong, nonatomic) NSArray *phones;
@end
// Address.m
@implementation Address
@end
import Foundation
class Address: NSObject {
var name: String
var email: String
var phones: [Phone]
override init() {
self.name = ""
self.email = ""
}
}
TBRJSONMapper *mapper = [[TBRJSONMapper alloc] init];
NSString *JSONFileInMainBundle = @"address";
Address *topAddress = [mapper objectGraphForJSONResource:JSONFileInMainBundle
withRootClassName:@"Address"];
let mapper = TBRJSONMapper(swiftModuleName: "SwiftExample")
let filename = "address"
if let address = mapper.objectGraphForJSONResource(filename, withRootClassName: "Address") as? Address {
// Do something with your address object
}
- There must be a root class in the JSON file, this will be the class returned to you.
- Classes start with a capital.
- Arrays (one-to-many relationships) end up with an s, i.e. 'Steps'.
- Properties in model classes must be mutable: You can't use 'var' in Swift or 'readonly' in Objective-C. This is because the mapper instantiates your model object first and then assigns the properties that are available afterwards.
These are all of the methods available in TBRJSONMapper:
- (instancetype)initWithSwiftModuleName:(NSString *)swiftModuleName;
When using TBRJSONMapper with swift, use this initializer to pass your project's module name.
- (id)objectGraphForJSONResource:(NSString *)resourcePath withRootClassName:(NSString *)className;
Use this method to get the root object with class className
when your JSON file is stored in your main bundle.
- (id)objectGraphForJSONData:(NSData *)data withRootClassName:(NSString*)className;
If you have already converted your JSON into NSData (for example, during archiving) use this method to map its content into your model. It returns the root object in the JSON object.
- (id)objectGraphForDownloadedJSONResourcePath:(NSString *)resourceName withRootClassName:(NSString *)className;
If you are storing a JSON file in some other directory other than your main bundle (for example, if your app has downloaded it from a server), you can use this method to pass a string containing the direct path to the JSON file (resourceName
) as well as the root class name. It will return the mapped top-level object.
The mapper has been tested a well as used in production with Swift.
In order to use it from Swift, you must pass the swift module name to the initializer, like this: TBRJSONMapper(swiftModuleName: "SwiftExample")
.
Your swift model classes must also inherit from NSObject
.
Nothing really happens, that property won't be mapped. However, if that JSON key refers to a class (one-to-one relationship) or a an array (one-to-many) you must provide it or the mapping will fail.
Yes you can.
The mapper uses Apple's NSJSONSerialization, so the supported types are the same. Have a look at NSJSONSerialization's class documentation for more details.