# 6 Common Mistakes with Protocols in Swift and How to Avoid Them

Protocols, an integral part of Swift, hold a significant place in Swift development. They help us define a blueprint of methods, properties, and other requirements for particular tasks or functionalities.

As wonderful as [protocols](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/) are, it's easy to make mistakes while using them, particularly when you are just starting with Swift. This post will outline some common mistakes developers make with protocols in Swift and how to avoid them. We will illustrate this with practical code examples.

### **1\. Confusion Between Protocol and Concrete Types**

One common mistake is confusing protocols with concrete types. Protocols define a blueprint, they cannot be instantiated directly. Let's see an example:

```swift
protocol Vehicle {
    var numberOfWheels: Int { get }
}

struct Car: Vehicle {
    var numberOfWheels: Int
}

let myVehicle: Vehicle = Vehicle()  // WRONG
```

In the above example, we're trying to create an instance of a protocol which isn't valid. Instead, we should instantiate a struct or class that conforms to that protocol:

```swift
let myVehicle: Vehicle = Car(numberOfWheels: 4)  // RIGHT
```

### **2\. Not Implementing Required Properties or Methods**

When a type promises to conform to a protocol, it must implement all the required properties and methods of that protocol. Forgetting to do so will lead to a compile-time error:

```swift
protocol Drawable {
    func draw()
}

struct Circle: Drawable {  // ERROR: Type 'Circle' does not conform to protocol 'Drawable'
}
```

The `Circle` struct says it conforms to `Drawable`, but doesn't implement the `draw()` method. The correct implementation would be:

```swift
struct Circle: Drawable {
    func draw() {
        print("Drawing a circle.")
    }
}
```

### **3\. Misunderstanding of Protocol Inheritance**

Protocols can inherit from other protocols, and this can sometimes lead to confusion. A common mistake is forgetting that a type conforming to a protocol that inherits from another protocol must satisfy the requirements of all protocols in its inheritance chain.

```swift
protocol Vehicle {
    var numberOfWheels: Int { get }
}

protocol MotorVehicle: Vehicle {
    var engineType: String { get }
}

struct Car: MotorVehicle {  // ERROR: Type 'Car' does not conform to protocol 'Vehicle'
    var engineType: String
}
```

In this example, `Car` conforms to `MotorVehicle` but does not provide the `numberOfWheels` property required by the `Vehicle` protocol. To fix this, we must provide all the required properties:

```swift
struct Car: MotorVehicle {
    var numberOfWheels: Int
    var engineType: String
}
```

### **4\. Expecting Protocols to Store State**

Swift protocols cannot store state. They can only declare properties, which must be implemented by the conforming types. This often confuses developers who come from class-based or object-oriented backgrounds.

```swift
protocol Drawable {
    var color: String { get set }  // Error: Property in protocol must have explicit { get } or { get set }
}
```

To avoid this, always remember that protocols are used to define a blueprint for methods and computed properties, not to store the state.

### **5\. Misuse of** `Self` in Protocols

When defining a protocol, `Self` is used to represent the current type. This can lead to problems if you try to use it in a way that doesn't make sense:

```swift
protocol Copyable {
    func copy() -> Self
}

struct Note: Copyable {
    var text: String

    func copy() -> Note {  // ERROR: Method 'copy()' in protocol 'Copyable' requires the return type to be 'Self'
        return Note(text: self.text)
    }
}
```

In the above example, we've defined a `Copyable` protocol with a `copy()` method that should return an instance of the conforming type. However, when we attempt to implement this in the `Note` struct, we specify `Note` as the return type instead of `Self`. This is incorrect because `Self` can refer to any type that implements the protocol (including any subclasses, in the case of classes), not just `Note`. The correct implementation would be:

```swift
struct Note: Copyable {
    var text: String

    func copy() -> Self {
        return Self(text: self.text)
    }
}
```

### **6\. Ignoring Associated Types in Protocols**

Another common mistake when using protocols is ignoring associated types. Protocols in Swift can contain associated type placeholders, which are replaced with a real type when the protocol is adopted. Here's an example of where this goes wrong:

```swift
protocol Container {
    associatedtype Item
    mutating func add(_ item: Item)
    var count: Int { get }
}

struct Stack: Container {  // ERROR: Type 'Stack' does not conform to protocol 'Container'
    var items = [Int]()
    
    mutating func add(_ item: Int) {
        items.append(item)
    }

    var count: Int {
        return items.count
    }
}
```

In the above example, `Stack` doesn't define what `Item` is, which leads to a compilation error. The correct way to implement the protocol would be:

```swift
struct Stack: Container {
    typealias Item = Int
    var items = [Item]()

    mutating func add(_ item: Item) {
        items.append(item)
    }

    var count: Int {
        return items.count
    }
}
```

By understanding these common mistakes and how to avoid them, you can start to harness the full power of protocols in your Swift applications. Remember, practice makes perfect. The more you use protocols, the more familiar you will become with their rules and nuances.

I hope you enjoyed this article, and if you have any questions, comments, or feedback, then feel free to comment here or reach out via [**Twitter**](https://twitter.com/iamnamitg).

Thanks for reading!
