The didSet attribute of a property Swift iOS

I’ve never used the Key Value Observer pattern (KVO) but I came across a situation that would otherwise call for it except for the Swift ability to call “didSet” for a property.

I’m making a view that partially pops up over a map when a map pin annotation is tapped with information about that annotation.  This pop up view has a number of labels and is initialized when the map first loads.  So, when the map first loads, there are no annotations selected and I can’t pass information to the pop up view (POV).  How do I get that information on to it?  I can simply set the labels when the annotation is tapped in my primary view controller (VC). That is, in the delegate function for pin annotation taps (calloutAccessoryControlTapped in my case). So the VC handles all that information.  But for my current project all that information, the datasource, or model, should not be handled by the VC.  Really the VC should only handle UI interactions and movement.  We’re actually using Model-View-View Model design, so we want all the model information and logic to be off the VC.  So one way to do this is to have the labels on the POV “listen” for new information and update when they here something has changed.

In Objective C, Key Value Observer pattern was a way to do just that.  In Swift it’s much simply. We simply use the “observers” didSet.

 

 Class SomeViewContoller: UIViewController {

 @IBOutlet weak var firstLabel: UILabel!
 @IBOutlet weak var secondLabel: UILabel!
 @IBOutlet weak var thirdLabel: UILabel!

 var viewModel: ViewModel {
    didSet {
    firstLabel.text = viewModel.someInfoProperty
    secondLabel.text = "Hey I'm using the view model to set this info: \(viewModel.getInformationForSentence)"
    thirdLabel.text = viewModel.convertPublicServiceAnnouncementsToHaiku
    }
 }

}

In this example, the viewModel property is setup so that when there’s a change, that is, when it’s set, the labels are updated accordingly.  There is a problem with this setup however – if the viewModel were to be set before the SomeViewController was intialized/loaded then we’d have a crash because the labels wouldn’t have been initialized yet.

didSet will not work for an init function – and shouldn’t.  If you want properties to be initialized to a certain value, just do that.