Applying Protocol-Oriented Programming in Development

Oct 17 2023 · Swift 5.9, iOS 17, Xcode 15

Lesson 03: Protocols & SwiftUI

Demo 1

Episode complete

Play next episode

Next
Transcript

Demo

In this demo, you’ll take your knowledge from the previous lessons and build some views using protocols. Open the starter playground in Xcode and run it. A simple view will appear.

The starter project contains many of the types from the previous lesson, allowing you to expand your Media project by building some views with it. The playground also has some code at the bottom to make it possible to display a View; currently, this just displays some text.

First, start by re-implementing the generic MediaCollection as a view called MediaCollectionView, then make it conform to View:

struct MediaCollectionView<T: MediaItem>: MediaCollection & View {
    var items: [T]
}

This looks similar to the previous lesson, but with the added feature of conforming to View through protocol composition. View requires a body property. Implement that next:

var body: some View {

}

To start, you’ll keep it simple and return a Text view:

Text("Hello SwiftUI")

Finally, change PlaygroundPage to return your new view:

let view = MediaCollectionView(items: [arkhamKnight, tearsOfTheKingdom])
PlaygroundPage.current.setLiveView(view.frame(width: 375, height: 667))

Run the playground. You’ll see your new text displayed.

Your next goal is to change the view to show some information from your media items. Change the generic type in MediaCollectionView to also be Identifiable.

struct MediaCollectionView<T: MediaItem & Identifiable>: MediaCollection & View

Identifiable is another protocol. It declares that the items it’s applied to must have a unique identifier to distinguish them from each other. The starter project already ensures that each MediaItem conforms to this and has an id property.

Now that you are able to distinguish all the items in items, you can use a list to display each item:

var body: some View {
    List(items) {
        Text($0.title)
    }
}

This now displays a list with more information from your media shelf! But you can make this even better.

Write an extension to make MediaItem conform to View itself:

extension MediaItem {
    var body: some View {
        Text(self.title)
    }
}

Now, make the generic type of MediaCollectionView conform to View as well:

struct MediaCollectionView<T: MediaItem & Identifiable & View>: MediaCollection & View 

Then, change the view implementation to return the new View directly:

var body: some View {
    List(items) {
        $0
    }
}

Finally, extend VideoGame to conform to View as well:

extension VideoGame: View {}

Since MediaItem already conforms to View, you don’t have to do anything else!

Run the playground. You’ll see the same list as before, but this time it’s using MediaItem directly as a View!

See forum comments
Cinema mode Download course materials from Github
Previous: Instruction Next: Instruction 2