DEV Community

Neeraj Gupta for DSC CIET

Posted on

Convenience Initializers and Failable Initializers in Swift

Brief Introduction About Swift

Swift is a language developed by Apple which is made using modern approach, include safety features and software design patterns. As the name suggests swift is fast, safe and easy to use. It is basically made a replacement for c-based family(C, C++ and Objective-C). It can be used to make apps and can be also used for cloud services and it is among the fastest growing languages.

Convenience Initializers

Designated initializers for classes are written in the same way as simple initializers for value types:

init(parameters) {
    statements
}
Enter fullscreen mode Exit fullscreen mode

Convenience initializers are written in the same style, but with the convenience modifier placed before the init keyword, separated by a space:

convenience init(parameters) {
    statements
}
Enter fullscreen mode Exit fullscreen mode

Swift applies the following three rules for Initializers:

  1. A designated initializer must call a designated initializer from its immediate superclass.
  2. A convenience initializer must call another initializer from the same class.
  3. A convenience initializer must ultimately call a designated initializer.

Convenience Initializers

This flow chart from swift documentation explains very well the above mentioned rules. Here, the initializers of subclasses are calling initializer of superclass and convenience initializer of respective classes are calling their designated initializers.

Here is a more complex example
Convenience Initializer

Here also the designated initializers of subclasses are calling the initializer of their superclasses and the convenience intializers.

We won't be going in much details but this is a basic idea of convenience init.

Failable Initializer

Let's understand using example

struct Person {
    var uniqueID: String
    init(personUniqueID: String) {
        self.uniqueID = personUniqueID
    }

}
let objectPerson = Person(uniqueID: "123456789012")
print(objectPerson.uniqueID) //123456789012
Enter fullscreen mode Exit fullscreen mode

So, above we created a structure which takes a unique ID for a person. Now, here we are considering that the unique ID is always of 12 digits. Now, what if a person passed some other String like "12345" then it would had printed 12345 as result. In, this case we need to apply some sort of validation. Let's see how

struct Person {
    var uniqueID: String
    init?(personUniqueID: String) {
        if personUniqueID.count < 12 {
            return nil //here this condition will run and return nil that means struct won't be created it will just get nil so here case of failable init comes in Xcode will provide us warning that "Only a failable initializer can return nil" so we will have to tell swift that this initializer is failable and we do that by adding "?" after init
        }
        self.uniqueID = personUniqueID
    }

}
let objectPerson = Person(uniqueID: "12345")
print(objectPerson.uniqueID)
Enter fullscreen mode Exit fullscreen mode

The line where we returned nil, here this condition will run and return nil that means struct won't be created it will just get nil so here case of failable init comes in and Xcode will provide us warning that "Only a failable initializer can return nil" so we will have to tell swift that this initializer is failable and we do that by adding ? after init.

Hope, you got the basic idea of convenience init and failable init. Thank you in case anyone want to add more to this post comment below.

Top comments (0)