Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Swift Protocol-Oriented Programming

You're reading from   Swift Protocol-Oriented Programming Increase productivity and build faster applications with Swift 5

Arrow left icon
Product type Paperback
Published in Jun 2019
Publisher
ISBN-13 9781789349023
Length 224 pages
Edition 4th Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Jon Hoffman Jon Hoffman
Author Profile Icon Jon Hoffman
Jon Hoffman
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Starting with the Protocol 2. Our Type Choices FREE CHAPTER 3. Extensions 4. Generics 5. Memory Management 6. Object-Oriented Programming 7. Protocol-Oriented Programming 8. Adopting Design Patterns in Swift 9. Case Studies 10. Other Books You May Enjoy

Protocol syntax

In this section, we will look at how to define a protocol and how to add requirements to it. This will give us a basic understanding of the protocol. The rest of this chapter will build on this understanding.

Defining a protocol

The syntax we use to define a protocol is very similar to the syntax that's used to define a class, structure, or enumeration. The following example shows the syntax that's used to define a protocol:

protocol MyProtocol { 
    //protocol definition here 
} 

To define the protocol, we use the protocol keyword, followed by the name of the protocol. We then put the requirements, which our protocol defines, between curly brackets. Custom types can state that they conform to a particular protocol by placing the name of the protocol after the type's name, separated by a colon. The following example shows how we would define that a structure conforms to a protocol:

struct  MyStruct:  MyProtocol  { 
    //Structure  implementation  here 
} 

A type can also conform to multiple protocols. We list the multiple protocols that the type conforms to by separating them with commas:

struct MyStruct: MyProtocol, AnotherProtocol, ThirdProtocol { 
    //Structure implementation here 
} 

Having a type conform to multiple protocols is a very important concept within protocol- oriented programming, as we will see later in this chapter and throughout this book. This concept is known as protocol composition. Now, let's see how we would add property requirements to our protocol.

Property requirements

A protocol can require that the conforming types provide certain properties with specified names and types. The protocol doesn't say whether the property should be a stored or computed property because the implementation details are left up to the conforming types.

When defining a property within a protocol, we must specify whether the property is a read-only or a read-write property by using the get and set keywords. We also need to specify the property's type since we cannot use type inference in a protocol. Let's look at how we would define properties within a protocol by creating a protocol named FullName, as shown in the following example:

protocol FullName { 
    var firstName: String {get  set} 
    var lastName: String {get  set} 
} 

In this example, we define two properties named firstName and lastName, which are read-write properties. Any type that conforms to this protocol must implement both of these properties. If we wanted to define the property as read-only, we would define it using only the get keyword, as shown in the following code:

var readOnly: String {get} 

It is possible to define static properties by using the static keyword, as shown in the following example:

static var typeProperty: String {get} 

Static properties are properties that are owned by the type and shared by all instances. This means that if one instance changes the value of this property, then the value changes for all instances. We will look at how to use static instances more when we look at the singleton pattern.

Now, let's look at how we would add method requirements to our protocol.

Method requirements

A protocol can require that the conforming types provide specific methods. These methods are defined within the protocol exactly as we define them within a class or structure, but without the curly brackets and method body. We can define that these methods are instance or type methods using the static keyword. Adding default values to the method's parameters is not allowed when defining the method within a protocol.

Let's add a method named getFullName() to the FullName protocol:

 protocol FullName  { 
    var firstName: String {get  set} 
    var lastName: String {get  set} 
 
    func getFullName() -> String 
} 

The FullName protocol now requires one method named getFullName() and two read- write properties named firstName and lastName.

For value types, such as the structure, if we intend for a method to modify the instances that it belongs to, we must prefix the method definition with the mutating keyword. This keyword indicates that the method is allowed to modify the instance it belongs to. The following example shows how to use the mutating keyword with a method definition:

mutating func changeName() 

If we mark a method requirement as mutating, we don't need to write the mutating keyword for that method when we adopt the protocol with a reference (class) type. The mutating keyword is only used with value (structures or enumerations) types.

Optional requirements

There are times when we want protocols to define optional requirements. An optional requirement is a method or property that doesn't need to be implemented. To use optional requirements, we need to start off by marking the protocol with the @objc attribute.

It is important to note that only classes can adopt protocols that use the @objc attribute. Structures and enumerations cannot adopt these protocols.

To mark a property or method as optional, we use the optional keyword. The following example shows how we would create both an optional property and also an optional method:

@objc protocol Phone { 
    var phoneNumber: String {get  set} 
    @objc optional var emailAddress: String {get  set} 
    func dialNumber() 
    @objc optional func getEmail() 
} 

If we are using the @objc attribute, as shown in the previous example, we cannot use the mutating keyword because it isn't valid for classes. Now, let's explore how protocol inheritance works.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime