Cleaner Swift MVVM with Property Wrapper | by Adityo Rancaka | Apr, 2022 | Medium

How I made @VMState property wrapper

Photograph by David Clode on Unsplash

I’ve seen quite a lot of iOS code constructed on high of the Mannequin-View-ViewModel (MVVM) design sample. Whereas element implementations would possibly fluctuate, there’s a single sub-pattern that everybody follows as a de facto precept of MVVM:

State Binding; It’s about binding any adjustments from the View Mannequin states to the View .

Let’s check out an instance of a QuantifierView:

QuantifierView

Projecting the View into View Mannequin illustration will produce the next Features and States:

Features:

  1. Improve
  2. Lower

States:

  1. Amount
  2. Error

Let’s deal with the State implementation for now.

Probably the most simple solution to implement this utilizing vanilla Swift can be to create two properties for every State in our ViewModel.

The primary one is the State itself, the opposite is an Observer that listens to the State mutations which takes a closure.

QuantifierViewModel

After which binding QuantifierViewModel with QuantifierView this manner:

Binding half in QuantifierView

The best way this work is fairly easy, each time QuantifierView makes a name to improve and lower features from the buttons, it is going to mutate the amount and error states inside QuantifierViewModel, then name the observers to replace the view labels.

Discover how QuantifierViewModel takes quite a lot of code only for defining a State together with its observer. The definition could be very repetitive. Wouldn’t it’s nice if Swift does have some form of mechanism to wrap round this repetitive habits and reuse it throughout all States in our View Mannequin?

Properly, sure it does!

Luckily ranging from Swift 5.1, there’s a function referred to as Property Wrapper that can be utilized to summary away extra habits of property behind its cute @ image. Combining with the ability of Generics, we are able to encapsulate our State’s frequent habits inside our new property wrapper referred to as @VMState:

Discover how clearly I’m simply copy-pasting our State definition from the View Mannequin to VMState.

There are two major elements in our new property wrapper for everybody to know with a view to grasp the concept.

The primary one is wrappedValue which is mainly the property (or State) and the opposite one is projectedValue which is the wrapper that wraps round our State’s habits.

Collectively they turn out to be a property wrapper.

In an effort to entry the projectedValue (or wrapper) we are able to use $ signal prefixed to our property.

@VMState var myState: Int // definition// invocation
print(sort(of: myState)) // Int
print(sort(of: $myState)) // VMState<Int>

With that in place, we are able to put it to use in our QuantifierViewModel to wash up repetitive code in our State definitions:

After which we are able to entry the projectedValue to assign observers for our States (binding) in our QuantifierView.

Whereas our @VMState works like a attraction, it’s nonetheless simply the tip of the iceberg. There’s nonetheless quite a lot of enchancment we are able to do comparable to assigning a number of observers to the State, deleting specific observers (identical to removeObserver in NotificationCenter), ignoring observer requires duplicate values, and so forth, and so forth.

Additionally, discover that Apple already has a built-in related method to this which is State from SwiftUI module. You probably have been slicing SwiftUI code or wielding the ability of Mix you would possibly discover VMState fairly acquainted to your sense.

More Posts