Swift – Chaining methods

Very often in Swift, you can see various methods called one each other and linked by a dot “.”.

These methods are called chained methods. Probably using Alamofire you already have seen this behaviour:

Alamofire
    .request("https://httpbin.org/basic-auth/\(user)/\(password)")
    .authenticate(user: user, password: password)
    .responseJSON { response in
        debugPrint(response)
    }

In this piece of code,

  • request
  • authenticate
  • responseJSON

are three different methods that return an Alamofire object (self).

It’s very easy to do, but let’s see how it works and how we can do the same things!

Let’s take a look at this basic class:

class StringOperationsWithoutChain {
    var theString = ""
    init(str: String) { theString = str }
    func appendZero() -> String { return "\(theString)0" }
    func appendOne()  -> String { return "\(theString)1" }
    func appendIcs()  -> String { return "\(theString)x" }
}

this class contains a simple init, and three (useless) methods.

You can use this class in this way:

let str = StringOperationsWithoutChain(str: "pippo").appendIcs()
print( str )

You create the class StringOperationsWithoutChain(str: ” “) and next you call one of the methods inside.

You can do the same with:

let str = StringOperationsWithoutChain(str: "pippo")
str.appendIcs()
print( str )

You’re able to do this because str is of type StringOperationsWithoutChain.

Let’s chain now:

We can use the same class, refactored to be chainable. All the functions that we want to use in a chain must return the class itself.

Example:

class StringOperations {
    var theString = ""

    init(str: String) { // chainable, returns implicitly self
        theString = str
    }

    func appendZero() -> StringOperations { // chainable
        theString += "0"
        return self
    }

    func appendOne() -> StringOperations { // chainable
        theString += "1"
        return self
    }

    func appendIcs() -> StringOperations {// chainable
        theString += "x"
        return self
    }

    // not chainable
    func printCallback(completion: @escaping (_ result: String) -> Void) {
        completion(theString)
    }
}

How to use this class?

// initialize
StringOperations(str: "pippo")

and next we can chain all the methods you want:

StringOperations(str: "pippo")
    .appendOne()
    .appendZero()
    .appendIcs()
    .printCallback { (result) in
        print( result )
}

You create a string “pippo” and next add “1“, “0” and “X” to this string and print in a callback the result.

As you can confirm, is very simple and very useful!

Result in the console:

pippo10x

Can be of course more interesting that appending values to a string. It’s just to make the idea and explain how it works.

Happy chain.

 

Alberto Pasca

Software engineer @ Pirelli & C. S.p.A. with a strong passion for mobile  development, security, and connected things.