Programming in Swift - Part 53: Part 6: Classes: | Ray Wenderlich

Learn how to create your own class initializers, including two-phase initializatoin, and required vs. convenience initializers.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3535-programming-in-swift/lessons/53

This topic was automatically closed after 166 days. New replies are no longer allowed.

It’s been a great course so far, and this is totally helping me with my carreer, but I’m still confused, do you have more examples about CI and DI to really know when to use them?. Thanks in advance :smiley:

@cmoyc Thanks very much for your question! The best way to understand Convenience/Designated Initializers is to use them in your projects. Simple examples usually are the best way to understand programming concepts so perhaps you should create your own examples, and apply the concepts from the video. That usually is the best way to see how the concepts work. If you do get stuck, or find that you’re getting an error, and are not sure why, you can most definitely post your question here, and we’ll be more than happy to answer it for you :slight_smile:

I hope this helps!

All the best!

1 Like

@cmoyc,
I hope you have seen the video and have some idea of what they are.

Here’s a summary crash course,

when you create a class

class Student {
  var name: String
  var age: Int
}

To be able to create an instance, you need to have an initialiser, this initialiser must initialise all the properties (that are not optional or have default values)


class Student {
    var name: String 
    var age: Int 

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
}

So now we have an initialiser this is the default or the designated initialiser. Each time we need to create a student object, this is the one that we will call.

A convenience initialiser is one that takes fewer or different parameters and instantiates the object and is tagged with the keyword convenience in front of it.
so we create the class as

class Student {
    var name: String 
    var age: Int 

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    convenience init(name: String) {
        self.init(name:name, age:18)
    }
    
}

and in a playground try this as

let john = Student(name:"John", age:42)
let jane = Student(name: "Jane")

print(john.age, jane.age)

Now let us add a new way to create a student, from a JSON dictionary

class Student {
    var name: String 
    var age: Int 

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    convenience init(name: String) {
        self.init(name:name, age:18)
    }
    
    convenience init?(json: [String:Any]) {
        // Convert the JSON into variables to use
        if let _name = json["name"] as? String,
        let _age = json["age"] as? Int {
            self.init(name:_name, age:_age)
            return 
        }
        return nil
    }

}

let john = Student(name:"John", age:42)
let jane = Student(name: "Jane")

let jsonCode:[String: Any] = ["name":"Jay", "age":99]

print(john.age, jane.age)

if let jay = Student(json: jsonCode) {
    print(jay.name, jay.age)
}

and yes, you will realise that as your code gets complex, you might have the need to write convenience initialisers.

cheers,

Jayant

1 Like

This is very helpful, this are great examples, and the JSON example totally hit the point that I wanted to understand, now I know that I’ll use convenience only in cases when I want to process certain data before calling the other inits. THANKS!

@cmoyc,
you are welcome :slight_smile:

cheers,

Jayant