Live Objects

Live Objects and Live Collection

In iOS AmitySDK, we have a concept of Live Object and Live Collection. LiveObject is represented by AmityObject instance and LiveCollection is represented by an instance of AmityCollection. They are generic classes which encapsulates any other object and notify observer whenever any property of encapsulated object changes.
Live Object helps to observe changes in a single object whereas Live Collection helps to observe changes in a list of objects. For example: AmityObject<AmityPost> or AmityCollection<AmityMessage>.

How it works

SDK handles lots of data received from various sources. Data can be present in local cache. It might also be queried from the server or received from some real-time events. What this means is that same data is constantly updating. The data that you are accessing at the moment can get updated by other sources and becomes out of sync.
Live Object and Live Collection helps in syncing the data so you will always get the most recent one. Whenever the data updates, you will be notified through helper methods in live object and live collection classes.
Both AmityObject and AmityCollection provide methods that help observe changes in objects. The life cycle of observation is tied to its token. As soon as the token is invalidated or deallocated, observation ends.

AmityNotificationToken

AmityNotificationToken is a simple object which keeps track of what is being observed. Each observation from live object or live collection is tied to its respective token. As soon as the token is invalidated or deallocated, observation ends. The token is declared within the scope of the class.
AmityNotification is alive in MyClass scope.
The token is used in combination with AmityObject or AmityCollection. We will explore it more in AmityObject and AmityCollection concepts.

AmityObject

AmityObject is a generic class that keeps track of a single object. It is a live object. In iOS AmitySDK, any object which is encapsulated by AmityObject is a live object.
Examples:
  • AmityObject<AmityMessage>
  • AmityObject<AmityChannel>
AmityObject class exposes the following methods:
  • observe
  • observeOnce
These methods help observe a live object. Whenever any property for observed object changes, the observer is triggered.

Observer

observe method can be triggered multiple times throughout the lifetime of the application as long as its associated AmityNotificationToken is retained in memory. observeOnce method, on the other hand, can only be triggered once.
Both observe and observeOnce methods will be called from the main thread so you can perform any UI update-related tasks from within the observe block itself.
  • If the requested object data is stored locally on the device, the block will be called immediately with the local version of the data. This can be verified through the dataStatus property of AmityObject.
  • In parallel, a request is made to server to fetch the latest version of the data. Once the data is returned, the observe block will be triggered again.
  • Any future changes to that data from any sources can trigger observer.
Lifecycle: The life cycle of observer is tied to its token. If the token is not retained, then observer can get deallocated at any time and will not be called. Both observe and observeOnce block will be retained using token as shown below.
Live Object observation is bound to a token

Invalidate token

The AmityNotificationToken provides a method called invalidate() which can be used to invalidate the token anytime. As soon as you invalidate the token, your observation stops and observe block will no longer be triggered.
Invalidate a token

Accessing Objects

There are multiple ways to access data from AmityObject. AmityObject exposes the following properties:
  • dataStatus: This defines whether data is fresh or local.
  • loadingStatus: This tells if the data is being loaded from server or not.
  • object: The actual object that is being tracked or encapsulated by this AmityObject
Once you add an observer block, you can access both local or fresh data as shown below.
Accessing live object properties
If you want to observe fresh object just once, you can check the data status and invalidate the token once you receive the fresh object.
Get a fresh object
For observerOnce method, if data is present locally, this observer will be triggered only once with that local data. If you are looking for fresh data, use the observe block and invalidate the token once fresh data is received as shown above.
If you only care about local data and do not want to observe anything, you can also access the object property from AmityObject directly.
Get a local data
While this is possible, we recommend accessing object from within theobserve or observeOnce block depending on your requirement.

AmityCollection

AmityCollection is a generic class that keeps track of a collection of objects. It is a Live Collection. In iOS SDK, any object which is encapsulated by AmityCollection class is a live collection.
Examples:
  • AmityCollection<AmityMessage>
  • AmityCollection<AmityChannel>
AmityCollection exposes these methods:
  • observe
  • observeOnce
These methods help observe a live collection. Whenever any property for any object within the collection changes, the observer is triggered.

Observer

observe method can get triggered multiple times throughout the lifetime of the application as long as its associated AmityNotificationToken is retained in memory.observeOnce, on the other hand, can only be triggered once.
Both observe and observeOnce method will be called from the main thread so you can perform any UI update related task within the observe block itself.
  • If the requested data collection is stored locally on the device, the block will be called immediately with the local version of the data. This can be verified through the dataStatus property of AmityCollection.
  • In parallel, a request is made to the server to fetch the latest version of the data. Once the data is returned, the observe block will be triggered again.
  • Any future changes to the data from any sources can trigger observer.
Lifecycle: The life cycle of the observer for AmityCollection is also tied to its token. If the token is not retained, the observer can get deallocated at any time and will not be called. So, both observe and observeOnce block should be retained. You can refer to the section in AmityObject about retaining and invalidating a token.

Accessing Collection

Unlike most databases, AmityCollection does not return all data in an array. Instead, data are fetched one by one using the objectAtIndex: method. This allows the framework to store most of the actual result on disk, and load them in memory only when necessary.
AmityCollection also exposes a count property which determines the number of objects present in a collection.
With these two public interfaces, you can create a robust list UI for your use case. Similar to AmityObject, AmityCollection also exposes dataStatus and loadingStatus property.
Let's look at the typical flow when accessing a collection data.
Observe a live collection
If you want to observe only fresh or local collection, you can access it using thedataStatus property and invalidate the token once you have accessed your desired collection data.
Observe a fresh live collection
For observerOnce method, if data is present locally, this observer will be triggered only once with that local data. If you are looking for fresh data, use observe block and invalidate the token once fresh data is received as shown above.
Observer also provides you with the AmityCollectionChange object which contains indexes of what is added, deleted, or modified in a collection. You can also refer to these properties to update the UI for the list.

Iterate through collection

While SDK provides liveCollection.object(at:) to access a single item, you might often find the need to iterate through all objects in the collection. The SDK has a convenient way to do this using .allObjects().
Iterate each object in a live collection using .allObjects()
Using the above method is the same with this logic:
An equivalent implementation of .allObjects()

Pagination

AmityCollection in SDK returns a maximum of 20 items per page. It has nextPage() and previousPage() method to fetch more data. It also exposes hasNext and hasPrevious property to check if next page or previous page is present.
Call nextPage() / previousPage() to load more data
Once next page is available, the same observe block gets triggered and you can access the collection as shown above. If you want to shrink the collection to the original first page, you can do so by calling resetPage() method on the same collection.
One typical usage of LiveCollection is in UITableView. Below is an example of fetching a collection and displaying it in a tableview.
Using a live collection with UITableView
Last modified 3mo ago