I’m an iOS team lead at IBM’s Mobile Innovation Lab in Austin. It’s been my privilege to be part of a talented team building a robust Watson iOS SDK written in Swift v2. The SDK’s first public release includes a collection of different offerings from Watson services, including Text to Speech, Speech to Text, Natural Language Classifier, Language Translation, Personality Insights, Dialog, Alchemy Vision, and Alchemy Language. One of the interesting early challenges with the project was picking the appropriate third-party tools to give out-of-the-box functionality without bloating the project with those very tools. We started using a popular tool called SwiftyJSON, which is a great tool for traversing JSON responses, but we found in some instances complex loops were needed to populate the model objects. Finally, we investigated a very nice lightweight mapping tool called Object Mapper and found it simplified the process. This open source tool makes it easy to convert model objects (Classes and Structs) to and from JSON — and it’s written in Swift! Check out the full set of features. Here is a code snippet from one of the Watson iOS SDK models. ```swift public struct Trait: Mappable { var ID:String? var name:String? var category:String? var percentage:Double? var samplingError:Double? var rawScore:Double? var rawSamplingError:Double? var children:[Trait]? public init?(_ map: Map) {} public mutating func mapping(map: Map) { ID <- map["id"] name <- map["name"] category <- map["category"] percentage <- map["percentage"] samplingError <- map["sampling_error"] rawScore <- map["raw_score"] rawSamplingError <- map["raw_sampling_error"] children <- map["children"] } } ``` As you can see in snippet, the mapping of the object is completed through the Mappable protocol and adheres to the mapping function. This is easily retrieved with a quick identifier in the map object passed into the map, such as ID <- map[“id”]. This nicely provides a one-line mapping with built-in recursion. Now, take another look at the property children; this array is of type Trait, which is the same object that holds children. In the mapping function, recursion is automatic — there’s no need to create a recursion loop. In turn, this creates a concise encapsulation of the data and how it is populated. A simple call, Mapper().map(response.data), is all it takes to populate the model object. In Watson iOS SDK, the response.data is returned as JSON from the Alamo Fire Framework. A deeper dive into the specifics of Object Mapper displays what’s going on with the <- characters in the mapping function. The Swift documentation version 2.1 sums it up nicely,
Swift gives you the freedom to define your own custom infix, prefix, postfix, and assignment operators, with custom precedence and associativity values. These operators can be used and adopted in your code like any of the predefined operators, and you can even extend existing types to support the custom operators you define.

wordCount <- map["word_count"]

A prefix is a unary operator located just before the value it operates on. A postfix is a unary operator located just after the value it operates on. And an infix is a binary operator located between the two values it operates on. Object Mapper has defined an infix operator which uses two values for manipulation, with one being the indexed map object and the other the receiver or the manipulated value. We found Object Mapper to be a really useful tool in creating Watson iOS SDK. If you want to dig deeper into operators and object mapping, there’s a lot more reading available:

1 comment on"Watson iOS SDK: Simplified object mapping"

  1. Peter Kasson April 05, 2017

    Vince,

    Great article highlighting the ObjectMapper project. I have been using it for some time, but just came across a new issue – recursion. Have you had to deal with that in your efforts and if so, how did you handle it ?

    Peter

Join The Discussion

Your email address will not be published. Required fields are marked *