SuperPlayer: A way to incorporate AVPlayer with The Composable Architecture
Tokopedia Play has become a demonstrative visual tour that showcases the looks and the benefits of the product listed on Tokopedia. Users can watch live or VOD content on Tokopedia Play. Other than Play, Tokopedia’s Feed and Product Detail Page also use videos to humanize the product experience.
In this article, we’re going to spill out a pinch of Tokopedia iOS’ secret recipe on how to built all video content and integrate it with many features in the app.
In Tokopedia Play, AVPlayer and AVPlayerItem are used as a playback engine for streaming live and VOD content. However, since AVPlayer and AVPlayerItem use the Key-Value Observing (KVO) pattern to publish their playback states that force developers to write some tedious code to observe some properties such as
loadedTimeRanges, etc. Writing a pool of KVO patterns would even result in a messier code base.
Tokopedia iOS app is built on top of The Composable Architecture or TCA for short. Using plain AVPlayer to play a huge number of media displayed will lead to a messy codebase because it is not designed for effective integration with TCA. Every feature that plays videos needs to observe AVPlayer properties with inconsistent design patterns. This will take more development time and make the code hard to read and maintain. It’s also hard to collaborate when all developers built the features using different design patterns.
- Subscribing to all common playback states from AVFoundation in the intermediate object
- Declaration of all the composable states, actions, and reducers for each playback state
- Send the playback states to the store using defined actions and write any shared playback logic in the reducer
With SuperPlayer, developers don’t need to write any code inside the intermediate object and can directly plug it into their TCA environment. Moreover, any playback logic can be written fully in Reducer and can be tested later with all unit test tools provided by TCA.
Consistent design patterns used among features can increase the readability and maintainability of the code. Building features with less code leads to saving more development time.
Refer to this link to see how SuperPlayer works.
ParentViewController has another TCA Store,
SuperPlayerAction can be directly associated with the parent TCA State and Action, then pullback the
SuperPlayerReducer to the parent Reducer. Only this time the SuperPlayer-scoped Store is the one that is going to be passed to the
Based on the picture, developers do not have to worry about writing AVPlayer repetitive code like declaring playback state subscription that happens on the green column or writing the TCA representation of AVPlayer that is covered on the blue column. They just need to worry about their feature on the yellow column and how it integrates with the player.
The purpose of the architecture is to compose a player to any TCA component. Developers don’t need to worry about handling the property’s subscription code because components like AVPlayer and AVPlayerItem will be represented in state, action, and reducer.
A struct that consists of AVPlayer subscribed properties. It also has an optional enum property named method of type
ComposablePlayerMethod that is going to be subscribed in the intermediate object to call the actual AVPlayer methods.
An enum that consists of AVPlayer methods representation such as
An enum that consists of actions to be sent from the actual AVPlayer object.
A logic to assign values from the intermediate object sent as
The implementation of
ComposablePlayerItem is very much similar to
ComposablePlayer. The only difference is that
ComposablePlayerItem represents the
A struct that acts as a parent state that holds
ComposablePlayerItemState. This is also the right place to extend other functionalities to the player.
A struct that contains states for populating the playback control UI.
An enum that is used to modify
SuperPlayerControlState and other extended states. It wraps
ComposablePlayerItemAction, and contains extended actions.
This is where the pullback declared for both
ComposablePlayerItemReducer. The logic inside can be executed when an intermediate object sent an action.
In addition to declaring the TCA components above, an intermediate object needs to be created to accepts
SuperPlayerViewController will act as the intermediate object that performs the actual subscription to both store and the
AVFoundation playback states.
SuperPlayerViewController is a
UIViewController type that has
AVPlayerLayer as its sublayer to display the video from
How to use
You can refer to this article to set up SuperPlayer. Let’s start over there!
Most pages and features in Tokopedia are built with TCA as their architecture. TCA provides a way to break down business logic that feels like composing Lego blocks.
SuperPlayer helps create a new video player block, so developers can directly plug it into their TCA environment. Any playback logic can be written in the reducer and can be tested with tools provided by TCA. With this consistent design patterns used among features can increase the readability and maintainability of the code that leads to saving more development time.
Want to make a suggestion or feedback? SuperPlayer is open source and we’re excited to hear and learn from you. Your experiences will benefit others who use SuperPlayer. Let’s make it even better!
Thanks to Adityo Rancaka to make SuperPlayer happen. Also kudos to all developers who helped make this happen.
An Ergonomic Approach To Incorporate AVPLayer With The Composable Architecture - Adityo Rancaka
As always, we have an opening at Tokopedia.
We are an Indonesian technology company with a mission to democratize commerce through technology and help everyone achieve more.
Find your Dream Job with us in Tokopedia!