Learn how to define a protocol in iOS development, a set of required and optional methods or properties that another class can implement, through a comprehensive and detailed tutorial.
This exercise is excerpted from Noble Desktop’s past app development training materials and is compatible with iOS updates through 2021. To learn current skills in web development, check out our coding bootcamps in NYC and live online.
Topics covered in this iOS Development tutorial:
Defining a protocol
Exercise Overview
A protocol is a set of required and optional methods or properties that another class can implement, or adopt. Think of a protocol as a blueprint or contract that a class adheres to. In this exercise, you’ll write your own protocol in our Car class.
Getting Started
Launch Xcode if it isn’t already open.
Go to File > Open.
Navigate to Desktop > Class Files > yourname-iOS App Dev 1 Class > Car Setup Done and double–click on Car.xcodeproj.
This code will be familiar from a previous exercise. But here we’ve created two separate files for the Car and Mustang class, as you will see in the Project navigator.
Defining a Protocol
Protocols are defined the same way that you declare classes and structs, only using the protocol keyword. Protocols are blueprints with properties and/or methods that are adopted. A type that follows the requirements conforms to that protocol.
In the Project navigator, select Car.swift.
-
Between the Engine structure and the Car class, around line 16, implement a protocol by typing the bold code:
struct Engine { var type = "" var horsePower = 0 } protocol CarDelegate { } class Car {
This is actually a delegate, which allows a class or struct to hand off responsibilities to an instance of another type. A delegate is an object that conforms to a delegation protocol and handles things for another object.
-
Now we need to add properties or methods that are part of the delegation protocol. Protocols only include function and property names—think of it like a list of requirements. Add a couple methods as shown in bold:
protocol CarDelegate { func starting() func didStart() }
These are two methods that you’ll use to track the state of the Car class. It’s common to want to have two classes talking to each other. For example, when you start the car, you want to trigger the starting method and present the user with an interface indicating that the car is starting.
In the Project navigator, select ViewController.swift.
-
At the top, add the bold code:
class ViewController: UIViewController, CarDelegate {
-
A red alert
will appear to the right of the line you just added. Click it.
It says: Type ‘ViewController
'
does not conform to protocol ‘CarDelegate'
Why did we get this error? The Car delegate describes two methods: starting and didStart. The class that adopts, or implements, the Car delegate needs to conform to the requirements of the protocol—which means follow all the methods defined in CarDelegate.
-
In order to do this you need to complete the implementation. Do this by adding the bold code as shown:
//DELEGATE METHODS func starting() { print("Car is starting. Display UI for user to indicate car is starting.") } func didStart() { print("Car did start. Add UI to let user know car has started.") }
In the Project navigator, go to Car.swift.
-
Now that you have the protocol defined, let’s use it. Create a delegate property with the type CarDelegate. Note that we’ve made it an optional:
var engine: Engine var delegate: CarDelegate? init(speed: Int, mpg: Float) {
-
Within the start method, around line 36, add the bold code:
func start() { self.speed = 10 self.delegate?.starting() print("Vroom") }
When the start method gets called, it will access the starting method outlined in the protocol, which in turn triggers the starting method in the class that adopts this delegate (in this case, the ViewController).
In the Project navigator, select ViewController.swift.
-
Add the bold code:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. mustang.delegate = self mustang.start() }
The mustang instance (which is inheriting the Car class) is going to set the delegate to this class. That means these methods will receive the callbacks for the methods in the protocol.
Go to Car.swift.
-
Add the bold code:
func start() { self.speed = 10 self.delegate?.starting() print("Vroom") self.delegate?.didStart() }
Time to test our code! At the top right, click the Show the Debug area button
if it’s not already showing.
-
At the top left of Xcode, click Stop
then click the Run button
.
The simulator will take a moment to load. At this point, it will just be a blank white screen.
-
Go back to the main Xcode window. Take a look at the Debug area to see the messages you specified in the print functions have printed:
The engine is revving
Car is starting. Display UI for user to indicate car is starting.
Vroom
Car did start. Add UI to let user know car has started. Save the file and keep Xcode open so that we can continue with this file in the next exercise.