Object Mapping in Swift

alicanbatur
NSIstanbul
Published in
3 min readOct 3, 2017

Hi all,

In this article, we will learn what object mapping is and importance of it. Then we will compare different ways of mapping an object in Swift.

What is mapping?

an operation that associates each element of a given set (the domain) with one or more elements of a second set (the range).” in terminology.

Where should we use mapping in real life?

Usually, when the request is completed, we receive the data in various formats. I choose JSON in examples below. These data formats should be converted to our models in our app. So that we will be able to use them as we want and in accordance with OOP. And those custom classes will let you code your model businesses in your custom classes.

Converting JSON to custom objects is necessary?

Yeap! Otherwise, you need to use them as dictionary, or some other data type. Which will make your app non-oop :)

Ways of mapping

There are many ways to map your objects.

Let’s start from the worst way, the non-mapping way :)

Swift’s basic way of mapping (Swift 3):

We have a person struct in the example above. First, we will add an init method to it.

init(with dictionary: [String: Any]?) {
guard let dictionary = dictionary else { return }
name = dictionary["name"] as? String
surname = dictionary["surname"] as? String
age = dictionary["age"] as? Int
}

Then map your object like this:

var data: Data = JSON.data(using: .utf8)!
let anyObj = try! JSONSerialization.jsonObject(with: data, options: .allowFragments)
let person = Person(with: anyObj!) // Maps here
label.text = person.name

If you need nilsafety, change models’ optional and set a default value:

var name: String?    ==>  var name: String!
var surname: String? ==> var surname: String!
var age: Int? ==> var age: Int!
...
name = dictionary["name"] as? String ?? "" // default value
surname = dictionary["surname"] as? String ?? ""
age = dictionary["age"] as? Int ?? 0

Open source mapping tools

Here are nearly all object mapping tool list. But I will show you some of them below. (awesome-ios#JSON)

struct Person: Mappable {
var name: String?
var surname: String?
var age: Int?
init?(map: Map) {

}

mutating func mapping(map: Map) {
name <- map["name"]
surname <- map["surname"]
age <- map["age"]
}
}
...
let person = Mapper<Person>().map(JSONString: JSONString)
// It also supports object to json
let JSONString = Mapper().toJSONString(person, prettyPrint: true)
// ObjectMapper also supports Alamofire(which I will write another blog about), Realm and a bunch of third parties.
// Mapping collections is also easy.
struct Person: Unmarshaling {
var name: String
var surname: String
var age: Int

init(object: MarshaledObject) throws {
name = try object.value(for: "name")
surname = try object.value(for: "surname")
age = try object.value(for: "age")
}
}
...
let people: [Person] = try json.value(for: "people") // A collection example
struct Person: Decodable {

let name: String?
let surname: String?
let age: Int?
// MARK: - Deserialization

init?(json: JSON) {
self.name = "name" <~~ json
self.surname = "surname" <~~ json
self.age = "age" <~~ json
}

}
struct Person {
let name: String
let surname: String
let age: Int
}

extension Person: Unboxable {
init(unboxer: Unboxer) throws {
self.name = try unboxer.unbox(key: "name")
self.surname = try unboxer.unbox(key: "surname")
self.age = try unboxer.unbox(key: "age")
}
}
...
let person: Person = try unbox(dictionary: dictionary)

There are many more tools that can be used. I wanted to show you some of them as an example.

Conclusion

Using mapping brings you benefits:

  • Domain Model Pattern usage.
  • Less code
  • Testability
  • Reusability
  • Single Responsibility. Dividing the model business

If you ask which one you are using, I will answer with ObjectMapper. Because I make my request calls with Alamofire, and ObjectMapper’s support for Alamofire is really useful. And also it supports realm objects which I choose to use for persistency. I plan to write a blog post about my service calls and mapping structure.

Please let me know if there is another really useful mapping tool you know with the benefits of it so that I can edit this post with that.

--

--