Protocols - OOP REVISITED - Understanding Swift Programming: Swift 2 (2015)

Understanding Swift Programming: Swift 2 (2015)

PART 4: OOP REVISITED

32. Protocols

A protocol is essentially a set of rules to be used in a particular situation. The term is often used in diplomacy and in medicine. A news report in October, 2014 stated that the first Ebola virus infection in the United States was caused by a "breach in safety protocol."

Some example text from one of the Ebola protocols: (just skim this quickly):

Ensure that a trained observer watches closely each donning and each doffing procedure of personal protective equipment, and provides supervisory assurance that donning and doffing protocols are followed.

The removal of used personal protective equipment is a high-risk process that requires a structured procedure, a trained observer, and a designated area for removal to ensure protection.

Personal protective equipment must be removed slowly and deliberately in the correct sequence to reduce the possibility of self-contamination or other exposure to Ebola virus. CDC recommends facilities use a powered air-purifying respirator.

A powered air-purifying respirator should have a full face shield, helmet, or headpiece. Any reusable helmet or headpiece must be covered with a single-use (disposable) hood that extends to the shoulders and fully covers the neck and is compatible with the selected powered air-purifying respirator.

This is just a tiny piece of a list of rules that is many pages long. What the protocols say is "If you are going to treat an Ebola patient, here is how you must do it."

The protocols for protecting against Ebola are very detailed and rigid—they have to be to avoid the spread of a deadly disease.

Diplomatic protocol is detailed and rigid so as to avoid initiating an embarrassing "incident", or even starting a war.

In programming, the concept is mainly used to allow groups of programmers to more easily use and reuse each other's code. If a programmer is building an API for iOS, he or she can define a protocol that says to the app programmers, "If you want to use this API, here is how you must do it." Typically this means "You must have methods with these names and input parameter types and return values that have these types" or "Your class must have properties with these names and types."

You might also use protocols in your own code even if it just for your own use, if you want to build frameworks or just standard methods that you can use in multiple apps so as to reuse code more effectively and make it easier to maintain.

Some developers claim that protocols are a sort of poor man's version of inheritance (usually offered up in discussions of Swift having only single inheritance, with the assertion that protocols are a form of multiple inheritance.) Until Swift 2, this was stretching it, because protocols didn’t actually cause methods and properties to be included in code. They only required programmers to put in something that fits certain syntactical requirements. And you can’t create an inheritance chain with protocols.

With Swift 2, classes, structures, and enumerations can obtain default implementations of methods and properties from protocols, and they can do so from more than one protocol at the same time. So protocols do start looking a bit like multiple inheritance.

Protocols have traditionally primarily promoted reuse of code by enforcing discipline. They can require that certain methods that have particular signatures be in the code. Such methods can be those that are outside of the existing inheritance chain for a class, or used in structures and enumerations (that don't have inheritance).

The concept of a protocol is similar to that of an interface, and in fact the Java programming language uses the term interface to define the rules of their version of a protocol. A Java programmer will then create a class that implements the interface, taking care to provide an implementation for those methods and other aspects of code that are specified as required by the interface. A Swift protocol does much the same thing.

It is often said that a protocol (or Java interface) forms a contract or agreement between the different pieces of code on how to work together.

In most cases while building an app, the protocols that you will be using are part of the iOS API.

Conforming to and Using a Protocol

Suppose you want to use table views in your app, which are a sort of elaborate vertical menu that allows you to scroll through information and select a menu item.

Table views require the app to conform to two protocols to use them, known as the UITableViewDataSource and UITableViewDelegate protocols. (If you Google, say, UITableViewDataSource Protocol Reference, you'll get a full description of all of the methods that are included in this protocol).

Among the methods in the UITableViewDataSource protocol that is required is a method known as numberOfRowsInSection.

The menu items in table views are known as rows, and if you like you can divide the rows into different groups, known as sections. Most table views just have one section, and the example here will have just one section.

When you use a table view, you will create a subclass of UITableViewController.

class Fruit: UITableViewController,UITableViewDataSource, UITableViewDelegate {

// Methods in class

}

When a class is defined, you must specify what protocols that the class will conform to. This means that the class agrees to follow the rules specified in the protocol. If the protocol requires a certain method with a certain signature, the class must implement it. If the protocol specifies asoptional a certain method with a certain signature, the class may implement it but is not required to. (Optional methods aren't quite what they might seem: The iOS API has many APIs with methods that are marked as optional, but are de facto required, because the API wouldn't actually work or be useful without them.) (Just to avoid confusion: Optional methods in protocols have nothing to do with Swift optional values.)

In the class definition, you specify the protocols you agree to conform to by listing them after a colon following the name of the class you have defined, in the same way that you would list the name of a superclass. This may seem confusing, but the compiler knows which names represent classes and which represent protocols. The one requirement here is that if there is a superclass, its name must come first.

If you specify a particular protocol in your class definition, you must include any methods and properties required by that protocol, or you will get an error message from the Xcode development environment.

So let's say that you want to have a table view that lists different kinds of fruits, along with their photo. And, pretty obviously, one of the things that you need to tell the API that will be creating your table view is how many menu items (fruits), that is, rows, will be in your table view.

The UITableViewDataSource protocol requires that you implement a method known as numberOfRowsInSection. In the typical menu, there is only one section, known as section 0, and you'll implement a method to tell the API that (not described here).

Then you will implement a method to tell the API how many rows need to be in the table. It will look something like this:

override func tableView (tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return 12

}

This method is called by the operating system, once the app code has requested a table view. This aspect of a method required by a protocol for an API is a little odd, because it seems backwards. Usually, your program calls a method. Here, the operating system is calling a method, and your job is to implement that method.

When the operating system calls the method you are implementing, tableView:numberOfRowsInSection:section, it will pass some parameters, including an integer labeled section. Since this table view has only one section, this parameter can be ignored. The only thing the method needs to do is to return an integer that reflects the number of rows needed for the table view, which for simplicity I have fixed to be 12, assuming that there are 12 different fruits and thus 12 rows.

(This is an oversimplification; the actual number you will return will be computed in a real situation according to what you need.)

Declaring A Protocol

You can declare your own protocol using the protocol keyword. For example, a protocol that requires the method getWeightOfPlant: might be defined as follows:

protocol PlantProtocol {

func getWeightOfPlant(aPlant: Plant) -> Double

}

The definition of the protocol includes the signature for any required functions—the keyword func, the name getWeightOfPlant, the input parameter(s), return arrow, and return type.

Declaring Protocols that Have Properties

Protocols can also define properties. These can be either stored or computed; the protocol makes no distinction, although it does specify whether the protocol can only be read or can both be read and written to.

The following protocol specifies a read-write property:

protocol PlantProtocol {

var a: Float { get set }

}

The following protocol specifies a read-only property:

protocol PlantProtocol {

var b: Int { get }

}

Declaring Protocols with Optional Methods/Properties

If a method or property is included in a protocol, it is required. However, it is often desirable to make use of a protocol but to not require particular methods or properties be used by a particular class that conforms to the protocol. They can be used or not, depending upon what is required for the particular app.

The following protocol definition specifies a method and a property that are both optional. (Again, this has nothing to do with Swift optional values.) A third property is also specified, but it is still required.

@objc protocol CalculationProtocol {

optional func doACalculation(c Int) -> Double

optional var a: Float { get set }

var b: Int { get }

}

To be able to mark a method or property as optional, you must put the @objc attribute in front of the protocol keyword. This normally specifies that a Swift class, method, or property can be accessed from Objective-C. But it is also used for another purpose—indicating that a protocol definition has a definition of something that is optional.

Hands-On Exercises

Go to the following web address with a Macintosh or Windows PC to do the Hands-On Exercises.

For Chapter 32 exercises, go to

understandingswiftprogramming.com/32