Tokopedia Play is an awesome platform which provides group chat where our users can interact closely with each other and Tokopedia agents. There is more awesomeness to that with offerings like Quizs, Polls, etc. Previously, Tokopedia Play on our iOS app was built using React Native, combined with UITableView (a native component which we customized) to show chats.
Our product and business teams fire on all cylinders during our promotions and TV events. And hence we were expecting to get more and more active users than previous events.
We identified that there were some problems in the bridge mechanism between the native side and React Native and under the heavy load, it wasn’t working in an expected manner occasionally. Such as the chat page was not rendering the right content or not in the right manner.
That’s a bit on the technical side. If we talk about the UI/UX or this flow, it changed drastically which had impacts on a mechanics and the components. On the other side, we were thinking if we continue to implement using React Native, it would require more effort to make and maintain.
With the above considerations, especially the performance things, we decided to rewrite the entire Tokopedia Play component using Swift.
Proposed solution & Architecture
Rewriting the flow also gave us a chance to think of some important aspects of architecture like scalability, maintainability, and testability. So, we broke it into the layers like domain layer, presentational layer, and service layer.
To explain it further, we’re using three ViewControllers, one is the ContainerViewController and the others as its children, so each ViewController can manage their own components independently. All logic, such as handling processed socket message being done at the container level, then passed down to related child components.
Let’s dive a bit deeper, the green one is ContainerViewController, the red one is a ViewController with video player and the last one with the blue line is MessageStreamViewController which contains message lists, and of course the message input component.
What made our development so Fast & Productive
Texture, as they say, is an iOS framework built on top of UIKit that keeps even the most complex user interfaces smooth and responsive. We used it as the underlying block to build our UI and keep it responsive at 60 fps as it calculates layouts in background. Since making UI layout using Texture is done by code, it boosts our productivity too.
One of the biggest issue with our productivity is higher compilation time. ⌘+R is our best friend and used repeatedly to test our iterations if everything looks as expected. How about running just your own code/module and test?
To switch to a faster track, we broke our codebase into modules. We created a separate module for Tokopedia Play and similarly, for other product offerings, some core components such as network layer, shared UI, and other abstractions are also placed on their own modules. And, now compilation for modules are independent and faster because we only compile what we work on.
Robust Socket Server + Existing Implementation
As mentioned earlier, Play was coded with React Native previously and we used Sendbird as messaging service. An then we moved to our in-house WebSocket server for stability, scalability, and flexibility. Kudos to our backend team of engineers for putting all of the efforts to make it happen.
We’re harnessing Starscream, which is a WebSocket client library in Swift, to interact with WebSocket server. We used this in our other offering, ChatBot, before so we already had a lot of learnings and a few best practice.
Well, there were many. We ware quite used to AutoLayout and were very comfortable with it. Texture was new to our team. So it had a learning curve in our team to adopt it. Because we had to use a different approach like flexbox on web development.
The multi-module approach also had its own challenges. We wanted to work in our own module but that has to work well with other modules as well so that we don’t have unnecessary culprits like build failure or even circular dependency that can happen if we’re not careful when playing with that.
A tight timeline was another challenge. After a lot of sweat, hard work and sleepless nights, we could deliver the best result to our beloved users and maintain our codebase quality.
Re-engineering the existing product from scratch, under a tight time constraint, with a lot of trial and error experiments, was very challenging. Also, we enjoyed every process from requirement gathering, system design, coding, testing until rolled out to production.
Make It Happen, Make It Better
We should continuously work to improve our code quality, architectural design, and of course the performance of our product. That’s necessary to achieve our goal to make the product is scalable, easy to maintain and testable because even Rome wasn’t built in a day.
Our product team is filled with crazily creative minds who think all the time to provide our customers with the best possible experiences. That might need more complex approaches in the code for not only Tokopedia Play but other modules also.
Focus on Consumer
Looking to join on our adventurous ride 💪🏼 to learn and contribute together to build better Tokopedia iOS apps? Check it out here 😉