NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

Why does Swift need protocols?

Paul Hudson    @twostraws   

Updated for Xcode 14.2

Protocols let us define how structs, classes, and enums ought to work: what methods they should have, and what properties they should have. Swift will enforce these rules for us, so that when we say a type conforms to a protocol Swift will make sure it has all the methods and properties required by that protocol.

In practice, what protocols allow us to do is treat our data in more general terms. So, rather than saying “this buy() method must accept a Book object,” we can say “this method can accept anything that conforms to the Purchaseable protocol. That might be a book, but it might also be a movie, a car, some coffee, and so on – it makes our simple method more flexible, while ensuring that Swift enforces the rules for us.

In code terms, our simple buy() method that works only with books would look like this:

struct Book {
    var name: String

func buy(_ book: Book) {
    print("I'm buying \(")

To create a more flexible, protocol-based approach we would first create a protocol that declares the basic functionality we need. This might be many methods and properties, but here we’re just going to say that we need a name string:

protocol Purchaseable {
    var name: String { get set }

Now we can go ahead and define as many structs as we need, with each one conforming to that protocol by having a name string:

struct Book: Purchaseable {
    var name: String
    var author: String

struct Movie: Purchaseable {
    var name: String
    var actors: [String]

struct Car: Purchaseable {
    var name: String
    var manufacturer: String

struct Coffee: Purchaseable {
    var name: String
    var strength: Int

You’ll notice each one of those types has a different property that wasn’t declared in the protocol, and that’s okay – protocols determine the minimum required functionality, but we can always add more.

Finally, we can rewrite the buy() function so that it accepts any kind of Purchaseable item:

func buy(_ item: Purchaseable) {
    print("I'm buying \(")

Inside that method we can use the name property of our item safely, because Swift will guarantee that each Purchaseable item has a name property. It doesn’t guarantee that any of the other properties we defined will exist, only the ones that are specifically declared in the protocol.

So, protocols let us create blueprints of how our types share functionality, then use those blueprints in our functions to let them work on a wider variety of data.

Hacking with Swift is sponsored by Waldo

SPONSORED Thorough mobile testing hasn’t been efficient testing. With Waldo Sessions, it can be! Test early, test often, test directly in your browser and share the replay with your team.

Try for free today!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.8/5

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.