Skip to content

Non Optionals & Optionals

Anton edited this page Jul 16, 2017 · 11 revisions

JSONModelKit supports mapping basic data types including String, Int, Double, Float and Bool. Let's look at a simple example for mapping basic datatypes for a Dictionary<String, AnyObject> response for a basic business case

Response Dictionary

{
    "business_uuid"  	: 9223123456754775807,
    "business_name"  	: 'NYC Restaurant',
    "business_rating" 	: 5,
    "business_longitude": 40.7053319,
    "business_latitude" : -74.0129945,
    "business_open"    	: 1
}

After receiving the data dictionary, the next step is to model the response into a class and map it accordingly. Unlike other mapping frameworks, where the developer needs to model the object first prior to mapping the response, JSONModelKit takes care of generating the model by creating a json mapping for a given model object. Let's go ahead and create a mapping for our Business model object, and add it to the mapping folder configured during installation.

Mapping

For each property that JSONModelKit will generate in the final model object, define a dictionary within the mapping file to represent each property. At minimum, you must define at least a key and a type entry. The key maps to the value of the response dictionary, and type defines the Swift datatype for that property. .

Model/Mappings/Business.json | PLIST Equivalent
{
    "uuid" : {
        "key" : "business_uuid",
        "type" : "Double",
        "nonoptional" : "true"
    },
    "name" : {
        "key" : "business_name",
        "type" : "String"
    },
    "rating" : {
        "key" : "business_rating",
        "subtype" : "Double"
    },
    "longitude" : {
        "key" : "business_longitude",
        "type" : "Float"
    },
    "latitude" : {
        "key" : "business_latitude",
        "type" : "Float"
    },
    "open" : {
        "key" : "open",
        "type" : "Bool"
    }
}

Model

Run the build script once ⌘+B. and you will see that it generated the following files in the output directory. This will also be reflected in the Project structure within the Model group

NOTE: Every time a new mapping configurations is added, the following build will always be canceled by Xcode, and needs to be run again. This is due to the project file changing in the middle of a build, since a new file is added. If no new mapping is added, it will build as usual.

From this example we'll find some new files in out project, an internal _Business.swift file, an external Business.swift class that extends from the latter, and a JMInstantiator.swift.

/Model/Internal/_Business.swift
import Foundation
import JSONModelKit

class _Business {

	var rating : Int?
	var uuid : Double?
	var longitude : Float?
	var latitude : Float?
	var open : Bool?
	var name : String?

 	required init() {...}

 	convenience init?(_ dictionary: Dictionary<String, AnyObject>) {...}
}

The internal file is where all the magic happens. At a high level, it provides a required initializer, and a Fail-able Initializer which takes in a Dictionary<String, AnyObject> to be parsed.

Observe the use of a nonoptional property being set to true in the mapping. Once the script has updated the internal file, the uuid property will be a non-optional property, and been added to the required initializer as an input parameter. In the case that the response dictionary does not contain a value for the uuid, the fail-able initializer will return nil.

/Model/Business.swift

import Foundation

class Business : _Business {
	// Add Custom Logic Here
}

The external file is for custom logic, and is only generated once, and will go unchanged if there is an update to the mapping. As a developer, one can add properties, methods, and implement any protocol as needed. The internal class is only there to hold reference to the values from the response dictionary is is being passed.