What is LiveData?
LiveData is an observable data holder class. Meaning, it respects the lifecycle of other app components, such as business logic, UI, or services.
This awareness ensures that LiveData only updates app component observers that are in an active lifecycle state.
LiveData notifies active registered objects about updates.
You can register an observer paired with an object that implements the LifecycleOwner interface.
This relationship allows the observer to be removed when the state of the corresponding Lifecycle object changes to DESTROYED.
This is especially useful for UI components (UIView, UIViewController) because they can safely observe LiveData objects without worrying about memory leaks — activities and UI components are instantly unsubscribed when they are Deinit.
How to use the LiveData step by step?
A class with generic data holder
Each time the data is set, we need to notify all registered observers.
Now our LiveData Class needs to have observers and methods to add/remove.
In this step, we can take a break and talk about memory leaks and life cycle.
As you know it’s really important to handle memory and avoid retain cycle.
In our case, if we deep dive into the add(observer: completion:) we can’t directly store the observer into our array of observers because this one is going to be retained as a STRONG reference to the array (which is a struct).
Now the question is: How to solve this problem?
- We can create a WeakBox or WeakWrapper for each observer.
- Each Wrapper will contain a weak reference of observer and the completion binding.
- What does it look like?
The full code with concrete Implementation.
The final deep dive, what’s wrong?
We solved a problem with the wrapper, but It’s not enough.
Why? because you need to manually remove the wrapper otherwise the object will be destroyed without the wrapper.
Because nobody is perfect and it is really easy to forget to remove this kind of object, like NSNotificationCenterObserver
To never forget to destroy all objects we can use the same logic as RxSwift! It consists of creating a DisposeBag instance and using the Deinit of this one to handle the object destruction.
It’s just because the DisposeBag instance shares the same life cycle then the observer. On RxSwift if you forget to define this instance, the compiler will generate a warning.
Step 7: How to use our beautiful LiveData class?
Playground use cases:
The sample code below represents a view which will be updated each time the value of Bool changes.
Printed result: 🥳🥳🥳
And that’s it :). We have learned how to start building a reactive object. The top advantages of using this kind of object are simplicity and reusability.
Each view can be updated with the same income data. And you do not have to import a heavy SDK to get ‘binding mechanisms‘
But I encourage you to take a look at Apple Combine, it’s really easy and nice to use and you will get free updates by Apple