Creating the Item Class

Your table view needs some rows to display. Each row in the table view will display an item with information such as a name, serial number, and value in dollars.

Create a new Swift file named Item. In Item.swift, define the Item class and give it four properties.

import Foundation
import UIKit

class Item: NSObject {
    var name: String
    var valueInDollars: Int
    var serialNumber: String?
    let dateCreated: Date
}

Item inherits from NSObject. NSObject is the base class that most Objective-C classes inherit from. All of the UIKit classes that you have worked with – UIView, UITextField, and UIViewController, to name a few – inherit either directly or indirectly from NSObject. Your own classes will often need to inherit from NSObject when they need to interface with the runtime system.

Notice that serialNumber is an optional String, necessary because an item may not have a serial number. Also, notice that none of the properties have a default value. You will need to give them values in a designated initializer.

Custom initializers

You learned about struct initializers in Chapter 2. Initializers on structs are fairly straightforward because structs do not support inheritance. Classes, on the other hand, have some rules for initializers to support inheritance.

Classes can have two kinds of initializers: designated initializers and convenience initializers.

A designated initializer is a primary initializer for the class. Every class has at least one designated initializer. A designated initializer ensures that all properties in the class have a value. Once it ensures that, a designated initializer calls a designated initializer on its superclass (if it has one).

Implement a new designated initializer on the Item class that sets the initial values for all of the properties.

import UIKit

class Item: NSObject {
    var name: String
    var valueInDollars: Int
    var serialNumber: String?
    let dateCreated: Date

    init(name: String, serialNumber: String?, valueInDollars: Int) {
        self.name = name
        self.valueInDollars = valueInDollars
        self.serialNumber = serialNumber
        self.dateCreated = Date()

        super.init()
    }
}

This initializer takes in arguments for the name, serialNumber, and valueInDollars. Because the argument names and the property names are the same, you must use self to distinguish the property from the argument.

Now that you have implemented your own custom initializer, you lose the free initializer – init() – that classes have. The free initializer is useful when all of your class’s properties have default values and you do not need to do additional work to create the new instance. The Item class does not satisfy this criteria, so you have declared a custom initializer for the class.

Every class must have at least one designated initializer, but convenience initializers are optional. You can think of convenience initializers as helpers. A convenience initializer always calls another initializer on the same class. Convenience initializers are indicated by the convenience keyword before the initializer name.

Add a convenience initializer to Item that creates a randomly generated item.

convenience init(random: Bool = false) {
    if random {
        let adjectives = ["Fluffy", "Rusty", "Shiny"]
        let nouns = ["Bear", "Spork", "Mac"]

        var idx = arc4random_uniform(UInt32(adjectives.count))
        let randomAdjective = adjectives[Int(idx)]

        idx = arc4random_uniform(UInt32(nouns.count))
        let randomNoun = nouns[Int(idx)]

        let randomName = "(randomAdjective) (randomNoun)"
        let randomValue = Int(arc4random_uniform(100))
        let randomSerialNumber =
            UUID().uuidString.components(separatedBy: "-").first!

        self.init(name: randomName,
            serialNumber: randomSerialNumber,
            valueInDollars: randomValue)
    } else {
        self.init(name: "", serialNumber: nil, valueInDollars: 0)
    }
}

If random is true, the instance is configured with a random name, serial number, and value. (The arc4random_uniform function returns a random value between 0, inclusive, and the value passed in as the argument, exclusive.) Notice that at the end of both branches of the conditional, you are calling through to the designated initializer for Item. Convenience initializers must call another initializer on the same type, whereas designated initializers must call a designated initializer on its superclass.

The Item class is ready for work. In the next section you will display an array of Item instances in a table view.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset