Hallo jassen en Jurken, Leo hier. Today we will talk about published properties and protocols in SwiftUI.

Last weekend I had a nice chat with my friends about getting old and the effects we already feel in our bodies. Interestingly, the most common aging effect is that we all eat less. When I was young I could easily eat 40 pieces of fried chicken, I don’t know why one would do that but that was possible.

And the thing is, the next day I had eaten so much fried chicken that I could feel the oil in my mouth, but besides that, I had zero side effects. Nowadays if I do the same I would wake up in a hospital. Another thing we discussed is that we started to have random pains, for example, when you don’t sleep in the right position and wake up with pain in your leg, neck, or back.

That never happened when we were young and nowadays is more common. And we have a very young developer among us lately from a College program in my company, and he plays football, etc, he said that you just need to take care of your body and nothing of those things that we mentioned would happen to him…

Well, unfortunately aging is not optional and we will all start to feel the side effects of aging sooner or later. I agree that a healthy life would increase the chances of a healthy life in general and we should pursue that. That’s is one of my goals for the next year, be more physically active and have a healthier life, let see how the year will progress in that matter.

Last week we discussed an interesting keyword in Swift that is used to mark any final implementation of a class. There we also discussed all the pros and cons of using it, and when you should use it in your codebase.

We also touched on a topic that is not so much mentioned by the tutorials because it is exclusive for people who need to give maintenance in a codebase, that is how to handle unavailability in Swift.

No more talking, let’s code! But first…

 

Painting of the Day

The 1518 painting I chose today is called Self Portrait with a Friend” by Raphael.

Raphael, a key figure in the High Renaissance and part of the great trinity of master painters with Michelangelo and Leonardo da Vinci, was renowned for his prolific work despite dying at 37. Born into an artistic family, he took over his father’s studio at 11 and was recognized as a master by 19. Known for blending Florentine art into his style, Raphael’s rivalry with Michelangelo and admiration for da Vinci shaped his career. Moving to Rome in 1508, his notable work in the Pope’s library led to further prestigious commissions.

I chose this because it reminds me of pair programming, like when I was pair programming to solve the protocol problem mentioned earlier.

 

The Problem – Update SwifUI with a Published inside a Protocol

You need to update a view state based on a protocol property.

Some time back, my good friend and I faced an intriguing challenge while working with SwiftUI. We aimed to ensure that two of the views use the same protocol as the view model. We understood that the view model was essential for asynchronously updating a property, and this update needed to be reflected in the view as well.

We tried several solutions, but in the end was easier than we thought.

The steps to follow are:

  1. Make the real implementation @Published
  2. Add ObservableObject to your protocol.
  3. Add in the view a generic property that is your protocol.

 

Check the full example below:

import SwiftUI

// real implementation
final class TimeStampViewModel: TimeStampPresentable {
    @Published var timeStamps: [String] = [] // Step one
    
    init() {
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] (timer) in
            self?.timeStamps.append("timer \(timer.fireDate)")
        }
    }
}

// protocol that all views can use
protocol TimeStampPresentable: ObservableObject { // Step 2
    var timeStamps: [String] { get }
}

// One view using the protocol
struct ContentView<ObservedViewModel>: View where ObservedViewModel: TimeStampPresentable { // Step 3
    @ObservedObject var viewModel: ObservedViewModel // Step 3
    let innerViewViewModel = TimeStampViewModel()
    
    var body: some View {
        VStack {
            Text("Time Stamp List")
                .font(.largeTitle)
            
            List(viewModel.timeStamps, id: \.description) { item in
                Text("\(item)")
            }
            
            InnerView(viewModel: innerViewViewModel)
                
        }
        .padding()
    }
}

// Another view using the same protocol
struct InnerView<T>: View where T: TimeStampPresentable {
    @ObservedObject var viewModel: T
    
    var body: some View {
        VStack {
            Text("Another View")
                .font(.largeTitle)
            
            List(viewModel.timeStamps, id: \.description) { item in
                Text("\(item)")
            }
        }
    }
}


#Preview {
    ContentView(viewModel: TimeStampViewModel())
}

Generating this proof of concept:

how to updating swiftui view with protocol tutorial

In the example above you can see the three steps mentioned before. We have the TimeStampViewModel that implements the TimeStampPresentable protocol, and the protocol is just saying that is an ObservableObject which indicates to all views that the properties can be updated any time using published and they should be observed. Then in the view you need to explicitly add a generic clause saying that the generic type is implementing the TimeStampPresentable.

And we are done!

 

Summary – Updating Your SwiftUI Views with a Published in a Protocol

In summary, the approach we’ve taken here exemplifies the power and flexibility of SwiftUI’s data flow concepts, particularly when combined with protocols and published properties. The TimeStampViewModel, through its adherence to the TimeStampPresentable protocol, ensures that any changes to its @Published property — the timeStamps array — are observed and reflected in the UI. This setup not only promotes a clean separation of concerns but also enables reusability and easy maintenance of your code.

What’s more, this example underscores a fundamental principle in modern iOS development: the importance of responsive and dynamic UIs that can adapt to changes in data.

Fellow iOS Developers, that’s all. I hope you liked reading this article as much as I enjoyed writing it.

If you want to support this blog you can Buy Me a Coffee or say hello on Twitter. I’m available on LinkedIn or send me an e-mail through the contact page.

You can likewise sponsor this blog and help our community to grow.

Thanks for the reading and…

That’s all folks.

Image credit: Featured Painting