Make Your Life Easier With Swift

Using Extensions to add (necessary) functionality

Objective-C, and now Swift have a fantastic way of allowing programmers to add functionality to any existing class, even if they don't have access to the original source code.

Of course this is a feature available in some other languages, but in this case, we'll focus on Swift, because it's Apple's up-and-coming language, which I happen to love.

One of the problems I was presented with recently, involved performing an action on a ViewController from the current navigation stack. Normally, Apple provides really good APIs for this:

public func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?)

But in the particular case with UINavigationController, there was no way of executing code after removing the ViewController. This presented a big problem, because I would either have to time the removal properly, or find a hacky way of synching the animation end and the code execution start:

public func popViewControllerAnimated(animated: Bool) -> UIViewController?

After looking a bit online, I found some interesting code:

CATransaction.begin()
CATransaction.setCompletionBlock(completion)
let controller = self.popViewControllerAnimated(animated)
CATransaction.commit()

This provided just the functionality I needed! Start a CoreAnimation (CA) transaction, set a completion block which executes after the transaction is done, and then execute the code to remove the ViewController from the stack.

Now the interesting bit here, is that, if not for extensions, I would have had to copy this code over and over. Instead, I was able to create a new extension to UINavigationController that contains the functionality, much in the same way as Apple's APIs:

extension UINavigationController {

    public func popViewControllerAnimated(animated: Bool, completion: (() -> Void)?) -> UIViewController? {
        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        let controller = self.popViewControllerAnimated(animated)

        CATransaction.commit()

        return controller
    }
}

And there we go, this extension provides just the functionality we need, without hacking, and even using the original functionality Apple provided.

Swift Tuples

Another nice feature in Swift are tuples. They are a group of values, represented by one value. It can be thought of as helper structs you make that are used as return types for functions. And this is exactly how they help out, the quick creation of a group of values that are related, but don't need a specific class to represent them.

func performAction() -> (bool, string?) {
return (true, "Success")
}

There is another great usage for them, switch statements. Remember those times when you had nested switches? Instead, you can use something like this:

switch (statusType, transactionType) {
case .Success, .Purchase:
 return "Purchase Successful"

 case .Success, .Reward:
 return "Reward Successful"

 case .Failure, _:
return "Failed Transaction"
}

One switch statement to handle all cases of one or more types. It is very useful for situations where inter-related enums or types need to be checked concurrently.

This is just the start of how useful tuples are. They are a fantastic addition to our repertoire of language features.

 

Author: Ricardo Chavarría
https://pa.linkedin.com/in/ricardochavarria