Intro to iOS Development
  • Welcome
    • ☀️Introduction
    • 🐣Getting Started
    • 🐦Course Staff
  • Logistics
    • 📜Syllabus
    • 🗓️Schedule
    • 🖊️Grading
    • 🙋‍♂️Office Hours
    • Ed Discussion
  • Assignments
    • 🍼A1: Swift Basics
    • 🧑A2: Profile
    • 💬A3: ChatDev
    • 👨‍🍳A4: ChefOS
    • 👨‍🍳A4: ChefOS - SwiftUI
    • 📱Hack Challenge
      • 🏆FA23 Winners
  • Lectures
    • 1️⃣Logistics + Swift Basics
    • 2️⃣UIKit + AutoLayout
  • 3️⃣MVC + Navigation + Delegation
  • 4️⃣UITableView
  • 5️⃣UICollectionView
  • 6️⃣Networking I
  • 7️⃣Networking II
  • 8️⃣SwiftUI I
  • 9️⃣SwiftUI II
  • 🔟Persistence + SnapKit
  • 🔔(11) Notifications
  • 🌎(12) Deployment and MapKit
  • Chapters
    • 🖐️Introduction
    • ☁️Git + GitHub
      • 1️⃣Git Installation
      • 2️⃣Git Basics
      • ➕Git+
    • 🐣Swift Basics
      • 1️⃣Variables and Constants
      • 2️⃣Data Types
      • 3️⃣Operators
      • 4️⃣Data Structures
      • 5️⃣Conditionals
      • 6️⃣Loops
      • 7️⃣Functions
      • 8️⃣Closures
      • 9️⃣Optionals
    • 🧰UIKit + AutoLayout
      • 1️⃣Classes
      • 2️⃣UIKit
      • 3️⃣AutoLayout
    • 📺MVC + Navigation + Delegation
      • 1️⃣MVC
      • 2️⃣Navigation
      • 3️⃣Delegation
    • 🏓UITableView
      • 1️⃣What is a UITableView?
      • 2️⃣UITableView Setup
    • 📚UICollectionView
      • 1️⃣What is a UICollectionView?
      • 2️⃣UICollectionView Setup
    • 🌐Networking I
      • 1️⃣HTTP Requests
      • 2️⃣Callbacks
      • 3️⃣Codable
    • 🌍Networking II
      • 1️⃣Alamofire
      • 2️⃣GET Requests
      • 3️⃣POST Requests
      • 4️⃣URLSession
    • 💾Persistence + SnapKit
      • 1️⃣Persistence
      • 2️⃣SnapKit
    • 🕊️SwiftUI
      • 1️⃣Introduction to SwiftUI
      • 2️⃣Getting Started with SwiftUI
      • 3️⃣Views + Modifiers
      • 4️⃣Layouts
      • 5️⃣Navigation
      • 6️⃣Property Wrappers
    • 🎛️Widgets
      • 1️⃣Introduction to Widgets
      • 2️⃣Setting Up Widgets
      • 3️⃣Building Widgets
      • 4️⃣Configuring Widgets
    • 🧱Project Foundation
    • ✅Testing
      • 1️⃣Unit Testing
    • 👣Debugging
      • 1️⃣OSLog
      • 2️⃣Crashlytics
      • 3️⃣Analytics
    • ☁️CI/CD
      • 1️⃣Xcode Cloud
      • 2️⃣AppStore Shipping
  • Guides
    • 🔨Xcode Project Setup
    • 🎨Figma
    • 📬Postman
    • 🥥CocoaPods
    • 🧰UIKit Handbook
    • 📑Tab Views
      • UITabBarController
      • TabView
  • Work in progress
    • 🧵Concurrency
    • 2️⃣UI Testing
    • 🕐Reactive Programming
    • 🧠Memory Management
      • 🔁ARC
    • 📦Storage
    • 📣Notifications
  • Archived
    • SP24
      • Logistics
        • 📜Syllabus
        • 🗓️Schedule
        • 🖊️Grading
        • 🙋‍♂️Office Hours
      • Assignments
        • 🍼A1: Swift Basics
        • 🧑A2: Profile
        • 💬A3: ChatDev
        • 👨‍🍳A4: ChefOS
        • 📱Hack Challenge
          • 🏆FA23 Winners
      • Lecture
        • 0️⃣Course Intro + Logistics + Git Setup
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • 🔟SwiftUI
        • 🔢TabViews
    • FA23
      • Logistics
        • 🐣Getting Started
        • 🐦Course Staff
        • 📜Syllabus
        • 🗓️Schedule
        • 🖊️Grading
        • 🙋‍♂️Office Hours
      • Assignments
        • 🍼A1: Swift Basics
        • 🧑A2: Profile
        • 💬A3: ChatDev
        • 👨‍🍳A4: ChefOS
        • 📱Hack Challenge
          • 🏆FA23 Winners
      • Lectures
        • 0️⃣Course Intro + Logistics
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • 🎛️Widgets
          • 👼Introduction to Widgets
          • ⚒️Setting Up Widgets
          • 🧱Building Widgets
          • 👨‍💻Configuring Widgets
        • 🔟SwiftUI
    • SP23
      • Logistics
        • Lecture Schedule
        • Syllabus
        • Grading
        • SP23 Office Hours
      • Chapters
        • 1. Intro to Swift & Xcode
          • Lecture Handout
          • Lecture Demo
          • 🍼Project: Swift Basics
        • 2. UIKit and AutoLayout
          • Lecture Handout
          • Lecture Demo
          • 🛒Project: UIKit + AutoLayout
        • 3. Navigation, MVC, and Delegation
          • Lecture Handout
          • Lecture Demo
          • Project: Navigation + Delegation
        • 4. UITableView
          • Lecture Handout
          • Lecture Demo
          • Project: UITableView
        • 5. UICollectionView
          • Lecture Handout
          • Lecture Demo
          • Project: UICollectionView
        • 6. Networking I
          • Lecture Handout
          • Lecture Demo
          • Project: Persistence
        • 7. Networking II
          • Lecture Handout
          • Lecture Demo
            • Message Board
          • Project: Networking II
        • 8. Swift UI
        • 9. CocoaPods
          • 🍫Lecture Handout
          • 🧑‍🍳Lecture Demo
      • Cheat Sheets
        • Setting Up a New Xcode Project
        • Submitting Your Projects
        • Setting Up CocoaPods
    • 2022
      • SwiftUI
    • 2021
      • Adding Flare
      • Project: UIView Animations (Optional - Extra Credit)
      • UIView Animations
      • Xcode Tips and Tricks
    • 2019
      • Firebase
      • Persistence: UserDefaults
  • Swift Guide (ARCHIVED)
    • About this Textbook
    • Documentation
    • Constants and Variables
      • Variable Properties
      • Lazy and Static Variables
    • Functions
    • Ranges
    • Arrays
      • Basic Array Operations
      • Iteration and Enumeration
      • Advanced Array Operations
    • Tuples
    • Conditions and While Loops
    • For Loops
    • Enums and Switches
      • Enums with Associated Values
      • Indirect Enums
    • Classes and Structs
    • Optionals
    • Dictionaries
      • Dictionary Implementation
    • Closures
    • Constraints
    • Generics
    • Protocols
      • Protocols With Associated Types
    • Casting
    • Errors
    • Networking
      • Result
    • Inout
Powered by GitBook
On this page
  • Protocols
  • Delegate vs Delegator
  • Putting everything together

Was this helpful?

Export as PDF
  1. Chapters
  2. MVC + Navigation + Delegation

Delegation

Fall 2023 | Vin Bui

PreviousNavigationNextUITableView

Last updated 1 year ago

Was this helpful?

This is one of the most important concepts to understand regarding iOS development using UIKit, and is one of concepts that students in the past have struggled with the most. Please read this section over and over again until you understand this concept. Feel free to ask the course staff if you are still confused.

The main purpose of the delegate pattern is to allow a child to communicate back with its parent without the child knowing its parent’s type. This makes it much easier to maintain and write reusable code. Delegation is a 1:1 relationship with a child and its parent.

Protocols

To implement delegation in Swift, we use protocols. According to Swift’s official documentation,

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol.

In other words, protocols are a set of properties and methods that classes must implement when conforming to it (similar to interfaces in Java).

protocol SomeProtocol: AnyObject {
    // Protocol definition here
}

You can learn more about protocols , but for our purpose, we will only need to define functions inside of the protocol. For example, If we wanted to create a protocol so that a child can tell its parent to update some text, we could do the following:

protocol UpdateTextDelegate: AnyObject {
    func updateText(newText: String)
}

Make sure to conform the protocol to AnyObject!

It’s convention to name our protocol with its purpose followed by the word Delegate at the end. We also created a function called updateText that takes in a string called newText. Now, if we had a class called ParentViewController and we wanted to conform to this protocol, we could do the following:

// Include `UpdateTextDelegate` in the class header
class ParentViewController: UIViewController, UpdateTextDelegate {
    // Class definition here

    // Must implement the function `updateText`
    func updateText(newText: String) {
        // Update some text given `newText`
    }
}

Now, it’s common to use an extension to implement these functions to keep our code a lot more neat:

// Remove `UpdateTextDelegate` from the class header
class ParentViewController: UIViewController {
    // Class definition here
}

// Add `UpdateTextDelegate`
extension ParentViewController: UpdateTextDelegate {
    func updateText(newText: String) {
        // Update some text given `newText`
    }
}

The only changes that we made was removing UpdateTextDelegate from the original class header and moved it to the extension header, followed by the function implementation required by the protocol.

Delegate vs Delegator

In the code above, we conformed ParentViewController to the UpdateTextDelegate protocol. The class ParentViewController is known as the delegate. The delegate is the class that conforms to that protocol.

Now, if we had a view controller called ChildViewController that wants to communicate back with the parent, then this view controller is known as the delegator. The delegator is the class that wants the delegate to do something by calling the delegate.

We’ve looked at the code required by the delegate, but what about the delegator? Inside of ChildViewController, we would create a property whose type will be UpdateTextDelegate:

class ChildViewController: UIViewController {
    // Class definition here

    // Create the property
    // If we make this private, an initializer is required
    weak var updateTextDelegate: UpdateTextDelegate?
}

How does this child class know who the delegate is? The parent class would need to specify that it itself is the delegate:

// Assume this class conforms to `UpdateTextDelegate`
class ParentViewController: UIViewController {
    // Class definition here

    // When we create an instance to `ChildViewController`, pass in
    // `self` as the delegate
    
    private func pushChildVC() {
        let childVC = ChildViewController()
        childVC.updateTextDelegate = self
        navigationController?.pushViewController(childVC, animated: true)

        // If the property `updateTextDelegate` is private, we will need
        // an initializer in `ChildViewController` that initializes it
	// and use this line instead
        let childVC = ChildViewController(updateTextDelegate: self)
    }
}

Now, once the child has a reference to its parent (specifically, a weak reference, will explain this in another chapter), we can now call that function:

class ChildViewController: UIViewController {
    // Class definition here

    // Create the property
    // If we make this private, an initializer is required
    weak var updateTextDelegate: UpdateTextDelegate?

    // Communicate with parent
    private func communicateBack() {
        let newString = "Here you go parent"
	updateTextDelegate.updateText(newText: newString)
    }
}

Note: In the example code above, we created the functions pushChildVC and communicateBack. These functions could be anything. What’s important is the code inside of the function.

Putting everything together

There was a lot of code and it could be quite difficult to wrap our head around, so let's put everything together.

There are two classes: ParentViewController (delegate) and ChildViewController (delegator). ParentViewController is the delegate so it conforms to the protocol, meaning that it is required to implement the functions and properties defined by that protocol. When ParentViewController creates the ChildViewController, it will need to tell it that it itself is the delegate. We do this by creating a property in ChildViewController containing the reference of the delegate (which is ParentViewController). To communicate from the child to the parent, the child calls the function defined in the protocol using the delegate property that was created earlier. This child could then pass in whatever it wants to the function (since it’s the delegator) and the parent (the delegate) will use whatever the child passed in and do whatever it needs to do.

Let’s take a real life example to understand this better. Say we went to a bar to have a couple of drinks. The bar contains a menu, a bartender, and a customer. The menu is the protocol, the bartender is the delegate, and the customer is the delegator. The bartender must conform to the menu. In other words, the bartender can only make drinks that are on the menu. But how does the bartender know what drinks to make? Well, the customer (delegator), tells the bartender (delegate) what drinks to make. In other words, the customer cannot make the drinks themself but requires the bartender to do it for them.

📺
3️⃣
here