30 Days of SwiftUI - Day 8: Exploring Protocols and Extensions in Swift

 

🧩 What’s a Protocol Anyway?

A protocol is a blueprint that defines methods, properties, or other requirements for conforming types. Think of it as a contract that ensures certain behaviors are implemented.

Example:

protocol Greetable {
    var name: String { get }
    func greet()
}

struct Person: Greetable {
    var name: String

    func greet() {
        print("Hello, my name is \(name)")
    }
}

let person = Person(name: "Gati")
person.greet() // Output: Hello, my name is Gati

✨ Building Bridges: Creating and Using Protocols

Protocols are created using the protocol keyword. Any struct, class, or enum can conform to the protocol by implementing its requirements.

Example:

protocol Flyable {
    func fly()
}

class Bird: Flyable {
    func fly() {
        print("Bird is flying high!")
    }
}

let sparrow = Bird()
sparrow.fly() // Output: Bird is flying high!

❓ Why Does Swift Need Protocols?

Protocols are vital in Swift because they: ✅ Enable code reusability. ✅ Support flexible and scalable designs. ✅ Allow types to share common functionality without inheritance.


πŸ” Opaque Return Types: What’s the Mystery?

Opaque return types use some to describe the type being returned without revealing its exact identity. This improves flexibility while maintaining type safety.

Example:

protocol Shape {
    func area() -> Double
}

struct Circle: Shape {
    var radius: Double
    func area() -> Double { 3.14 * radius * radius }
}

func createShape() -> some Shape {
    return Circle(radius: 5)
}

let shape = createShape()
print(shape.area()) // Output: 78.5

🧱 Extensions: Adding Power to Existing Types

Extensions let you add new functionality to existing classes, structs, enums, or protocols without modifying the original code.

Example:

extension Int {
    func squared() -> Int {
        return self * self
    }
}

print(4.squared()) // Output: 16

πŸ› ️ When Should You Use Extensions in Swift?

✅ To organize code more efficiently. ✅ To add functionality to types you don’t own (e.g., String, Int). ✅ To improve code readability and maintainability.


πŸš€ Protocol Extensions: Powering Up Protocols

Protocol extensions allow you to provide default implementations for protocol methods, reducing redundant code.

Example:

protocol Identifiable {
    var id: String { get }
    func identify()
}

extension Identifiable {
    func identify() {
        print("My ID is \(id)")
    }
}

struct User: Identifiable {
    var id: String
}

let user = User(id: "12345")
user.identify() // Output: My ID is 12345

πŸ€” When Are Protocol Extensions Useful?

✅ To provide shared functionality across multiple conforming types. ✅ To reduce code duplication by offering default method implementations. ✅ To extend protocols in a modular way.


✅ Checkpoint Challenge: Test Your Skills!

Question: Create a protocol called Vehicle with a speed property and a move() method. Use a protocol extension to provide a default implementation for move().

Answer:

protocol Vehicle {
    var speed: Int { get set }
    func move()
}

extension Vehicle {
    func move() {
        print("Moving at \(speed) km/h")
    }
}

struct Car: Vehicle {
    var speed: Int
}

let myCar = Car(speed: 100)
myCar.move() // Output: Moving at 100 km/h

πŸ“Œ Summary: Key Takeaways

Protocols define rules that types must follow. ✅ Extensions add new features to existing types without inheritance. ✅ Protocol extensions allow default implementations to reduce redundancy. ✅ Opaque return types enhance flexibility while ensuring type safety.


Follow me on Linkedin: igatitech πŸš€πŸš€πŸš€

Comments

Popular posts from this blog

30 Days of SwiftUI — Day 1: Getting Started with SwiftUI

30 Days of SwiftUI Learning Journey: From Zero to Hero!

30 Days of SwiftUI - Day 11: Building Interactive SwiftUI Apps