iOS Developer: From Noob to Ninja in 30 days — Day 4 Protocols Use Cases in Classes, Structs and Enums

In this post I will be talking about protocols in Swift and the things you should know about protocol applied to classes, structs and enums.

Tony Trejo
8 min readNov 25, 2020

What is a protocol?

A protocol is something that defines a particular use case. The protocol can defines methods, properties and other necessary pieces used by whoever complies with that protocol.

Let’s create different types of protocols, without any property or method.

protocol SimpleProtocol { // 1
}
protocol ClassProtocol: class { // 2
}
protocol AnyObjectProtocol: AnyObject { // 3
}
protocol AnyProtocol: Any { // 4
}
protocol ObjectProtocol: NSObject { // 5
}
@objc protocol ObjcProtocol { // 6
}
  1. This is the default syntax of one protocol.
  2. This is a protocol that inheritance from class, so for that reason this protocol is limited only to classes (you can not use this protocol in structs or enums), another important thing to know if that class is deprecated in favor of AnyObject simply without a warning.
  3. This is a protocol that inheritance from AnyObject, so for that reason this protocol is limited only to classes and it is the correct way to do that.

Note: AnyObject is the protocol to which all classes implicitly conform, defined in the swift code as public typealias AnyObject.

4. This is a protocol that inheritance from Any, can represent an instance of any type at all, that means we can use that protocol anywhere you want.

5. This is a protocol that inheritance from NSObject, in Objective-c NSObject is the root class and conforms NSObjectProtocol.

Note: The NSObjectProtocol provides common methods and properties like

- description
- func responds(to aSelector: Selector!) -> Bool
- func perform(_ aSelector: Selector!) -> Unmanaged<AnyObject>!
- etc.

6. Protocol marked objc, in theory that protocol only can be conformed by a class that inheritance from NSObject.

Now that we have those protocols let’s apply them to a class, struct and enum.

It is very common to use protocol in an extension, an extension basically consists on adding some functionalities in another block of code.

I you want to know more about extension the link below can help you with that.

How to use a protocol in a Class?

It is very easy to conform a protocol in a class you just need to add the operator “:” after the class declaration.

As you can see it is possible to conforms almost all the protocols, but there is an error and the meaning of that is the class needs to inheritance from NSObject.

If we add the inheritance from NSObject to the class, now we will be able to conform the ObjectProtocol.

class CryptoExchange: NSObject { }

How to use a protocol in a Struct?

Conforming a protocol in a struct is the same as a class.

We can see many errors in this case, I will explain each one.

When the struct tries to conforms the ClassProtocol produces an error.

Non-class type 'CryptoExchange' cannot conform to class protocol 'ClassProtocol'

This error is because the ClassProtocol inheritance from class, that means that protocol only can be applied to a class, doesn’t work in a struct.

Non-class type 'CryptoExchange' cannot conform to class protocol 'AnyObjectProtocol'

This error is because the AnyObjectProtocol inheritance from AnyObject, that means that protocol only can be applied to a class doesn’t work in a struct.

Non-class type 'CryptoExchange' cannot conform to class protocol 'ObjcProtocol'

This error is because the ObjcProtocol is marked as objc, that means that protocol only can be applied to a class, doesn’t work in a struct.

Non-class type 'CryptoExchange' cannot conform to class protocol 'ObjectProtocol'

This error is because the ObjectProtocol inheritance from NSObject, that means that protocol only can be applied to a class, doesn’t work in a struct.

How to use a protocol in an Enum?

Conforming a protocol in an enum is the same as a struct.

As you can see conforming those protocols gave us the same errors like a struct, this is because an enum and the struct both are value type.

How to add properties in a protocol?

Let’s create a protocol called ExchangeProtocol that provides two properties, one of them will be the name of the exchange and another the called city.

protocol ExchangeProtocol {
var name: String { get set }
var city: String { get }
}

Then let’s add that protocol to the class, struct and enum.

  • Class conforming ExchangeProtocol (properties)

First we conform the ExchangeProtocol in a class.

When you try to conform that protocol you will see that message, that means you need to conform that protocol (add the properties and methods that defines that protocol) like I show you below.

If you pressed fix, then the Xcode will add that properties (computed properties) to your code.

But there is something important here, in the property name there are a get and set, this is because the protocol defines name { get set } values, that means you name property can be variable.

In the case of property city that means is a constant you only can set that value in the init or a hardcoded value.

A common error is try to add an init in a extension, you can not do that.

Let’s move that code to the class definition and create an instance.

As you can see now is working fine.

  • Struct conforming ExchangeProtocol (properties)

Now let’s try the same in a struct.

As you can see it is very similar to the class, but remember the struct has an automatic initializer so we can remove that initializer and the code looks like this.

Remember a struct is value type and if you want to use a protocol that protocol has not inheritance from any class type (reference type).

  • Enum conforming ExchangeProtocol (properties)

And last but not least let’s do that in an enum.

As you can see we can not do the same with an enum for the reasons below.

  1. The enum will need computed properties.
  2. Remember that an enum is just the representation of different cases within a specific context.
  3. You can create an init for the enum but that is not the usual use case for an enum.

To fix the enum we can add a case call info.

If you want to learn more about computed properties you can see the link below.

If you want to know more about enums the link below can help you with that.

How to add methods in a protocol?

Continue working with the ExchangeProtocol lets add two methods (sell and buy).

protocol ExchangeProtocol {
// Properties
var name: String { get set }
var city: String { get }
// Methods
func sell()
func buy()
}

The important thing to know about a protocol is that ensure that any type that conforms that protocol will have those properties and methods but the implementation should be created in the class, struct or enum conformed that protocol.

Then let’s add that protocol to the class, struct and enum.

  • Class conforming ExchangeProtocol (methods)

First we conform the ExchangeProtocol in a class.

As you can see now we are able to set the implementation for sell and buy action.

  • Struct conforming ExchangeProtocol (methods)

As you can see it is the same implementation for a struct.

  • Enum conforming ExchangeProtocol (methods)

Now conforming ExchangeProtocol in an enum looks like this.

There are many special topics about protocols I really recommend you to read the other posts that I shared you.

Important things to know

  • Does the protocol can inheritance?

Yes it does, usually called protocol inheritance, one protocol can inherit from another.

  • A class can conform any protocol.

Note: There are some specialized protocols if you want to know more about those the link below can help you with that.

  • A struct or enum can not conforms protocols that inheritance from class, AnyObject, marked as objc and NSObject.
  • A class, struct or enum can conforms multiple protocols, you just need to add a comma after each protocol.
protocol FirstProtocol {}protocol SecondProtocol {}protocol ThirdProtocol {}class ClassExchange: FirstProtocol, SecondProtocol, ThirdProtocol {}struct StructExchange: FirstProtocol, SecondProtocol, ThirdProtocol {}enum EnumExchange: FirstProtocol, SecondProtocol, ThirdProtocol {}

Or you can use extensions like this.

class ClassExchange { }extension ClassExchange: FirstProtocol { }extension ClassExchange: SecondProtocol { }extension ClassExchange: ThirdProtocol { }struct StructExchange { }extension StructExchange: FirstProtocol { }extension StructExchange: SecondProtocol { }extension StructExchange: ThirdProtocol { }enum EnumExchange { }extension EnumExchange: FirstProtocol { }extension EnumExchange: SecondProtocol { }extension EnumExchange: ThirdProtocol { }
  • The protocol doesn’t contain any implementation for his properties and methods.
  • You can make the optional the protocol methods, you can learn more in the link below.

Resources

  • Apple’s protocol definition
  • Protocol inhetance
  • NSObjectProtocol

I think is enough for this post. I’ll be working on the next post don’t forget to follow me and if you are interested in personal training let me know.

Steve Jobs: “The people who are crazy enough to think they can change the world are the ones who do”.

--

--