Initializers in swift part-2: Failable Initializers in swift

This is the part two of my “Initializers in swift” article.

Here is the first part: Initializers in swift part-1 : (intro, convenience and designated intializers)

Failable Initializers :

We cannot always assume that the initialization will always succeed for a struct, enum or class. It can fail for several reasons. It is sometimes useful to define a class, structure, or enumeration for which initialization can fail.

// failable initializerlet wholeNumber: Double = 12345.0if let valueMaintained = Int(exactly: wholeNumber) {print(“\(wholeNumber) conversion to Int maintains value of \(valueMaintained)”)}
struct Animal {let species: Stringinit?(species: String) {if species.isEmpty { return nil }self.species = species}}
let someCreature = Animal(species: "Giraffe")// someCreature is of type Animal?, not Animalif let giraffe = someCreature {print("An animal was initialized with a species of \(giraffe.species)")}// Prints "An animal was initialized with a species of Giraffe"

Failable Initializers for Enumerations

Read my article about enums and raw values here.

enum TemperatureUnit {case kelvin, celsius, fahrenheitinit?(symbol: Character) {switch symbol {case "K":self = .kelvincase "C":self = .celsiuscase "F":self = .fahrenheitdefault:return nil}}
__________________________
guard let fahrenheitUnit = TemperatureUnit(symbol: "X") else {print("This is not a defined temperature unit, so initialization failed.")}// Prints "This is not a defined temperature unit, so initialization failed."

Failable Initializers for Enumerations with Raw Values

Enumerations with raw values automatically receive a failable initializer, init?(rawValue:), that takes a parameter called rawValue of the appropriate raw-value type and selects a matching enumeration case if one is found, or triggers an initialization failure if no matching value exists.

enum TemperatureUnit: Character {case kelvin = "K", celsius = "C", fahrenheit = "F"}let fahrenheitUnit = TemperatureUnit(rawValue: "F")if fahrenheitUnit != nil {print("This is a defined temperature unit, so initialization succeeded.")}// Prints "This is a defined temperature unit, so initialization succeeded."

Propagation of Initialization Failure

If your subclass is having a failable initializer which in turn call its superclass failable designated initializer, then if either of the initialization failed means the entire initialization process fails immediately, and no further initialization code is executed.

class Product {let name: Stringinit?(name: String) {if name.isEmpty { return nil }self.name = name}}class CartItem: Product {let quantity: Intinit?(name: String, quantity: Int) {if quantity < 1 { return nil }self.quantity = quantitysuper.init(name: name)}}
_____________________
if let zeroShirts = CartItem(name: "shirt", quantity: 0) { // failsprint("Item: \(zeroShirts.name), quantity: \(zeroShirts.quantity)")} else {print("Unable to initialize zero shirts")}// Prints "Unable to initialize zero shirts"______________________if let oneUnnamed = CartItem(name: "", quantity: 1) { // failsprint("Item: \(oneUnnamed.name), quantity: \(oneUnnamed.quantity)")} else {print("Unable to initialize one unnamed product")}// Prints "Unable to initialize one unnamed product"

Overriding a Failable Initializer

You can override a superclass failable initializer in a subclass, just like any other initializer. Alternatively, you can override a superclass failable initializer with a subclass nonfailable initializer. This enables you to define a subclass for which initialization cannot fail, even though initialization of the superclass is allowed to fail.

The init! Failable Initializer

You typically define a failable initializer that creates an optional instance of the appropriate type by placing a question mark after the init keyword (init?). Alternatively, you can define a failable initializer that creates an implicitly unwrapped optional instance of the appropriate type. Do this by placing an exclamation mark after the init keyword (init!) instead of a question mark.

If you enjoyed reading this post and found it useful, please share and recommend it so others can find it 💚💚💚💚💚💚 !!!!

Thanks!!

iOS and tvOS developer, dreamer, photographer 🤨

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