Nerd For Tech
Published in

Nerd For Tech

Convenience Initializers in Swift

Photo by Karl Pawlowicz on Unsplash

Initializers in swift give us the flexibility to customize how our custom classes are initialized when created. In Swift, Apple has created multiple initializers within their frameworks giving developers more options to instantiate objects with different configurations. More often than not, it will be necessary to write our own initializers for our custom classes.

Imagine we are working on an app that requires multiple labels. We are building the app programmatically and the labels require some custom styling. We might start by overriding one of the label’s designated initializer to setup our custom class.

To keep our initializer clean we will use a custom configure function to hold our label’s customization.

With our label’s designated init overridden and our configure function in place, we can start customizing. (Note we have to also implement the required init using NSCoder that will fire off and crash our app if there was a problem creating our object from our custom initializer)

Our CustomLabel class now has unique styling for our app. While this definitely works, our label is not very dynamic: each label we create will have this exact styling each time. If we wanted to change the textColor for example, we’d have to change it somewhere within the lifecycle of our app. This implementation is not exactly convenient; there is an easier way!

Within our custom classes, we can create connivence initializers, giving our objects more flexibility and decoupling our code making it reusable. Now you may be thinking that adding a whole another initializer to our custom classes is more code, and you’d be right, however it cleans up other files in our project where our objects are instantiated at.

In order to create our convenience init, we start with the convenience keyword before our initializer, telling Xcode that this initializer can be used to instantiate our label. As you can see we get an error stating ‘self.init’ isn’t called on all paths before returning from initializer. What does this mean? In order to call our convenience init we must also call one of the parent object’s designated initializers within our initializers. The Swift documentation tells us:

Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.”

Earlier we overrode our label’s parent initializer init(frame:) and called our custom function, we simply need to call this initializer within our convenience init and then we can add our dynamic code for our label.

Note that the init(frame:) being called within the convenience init is the init that we overrode.

Our configure function will be called automatically when we use our convenience init, allowing us to separate out the code we want to be dynamic.

Our convenience init is now ready to be used! The configure function we wrote now only holds code that we don’t want to change between each label we create! Now when we create our CustomLabels, Xcode will give us the option to use our new init and handle the construction of the labels by automatically calling the designated init, then applying our custom code.

Convenience initializers do add more code to your custom classes, but they also clean up the call sites of where your objects are being used by allowing you to initialize dynamic code from duplicate objects.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Herbie Dodge

Herbie Dodge

iOS Developer | Swift | Looking for new opportunities 🚀