Implementing Native UI from Scratch Using JSON

At Farfetch, we have developed a Native Mobile UI (NMUI) framework which we use to assemble our iOS apps. This framework enables us to build complex screens very quickly while still being fully native. Currently, we are transitioning some of our development flow to use this framework because we think it has many benefits. In this article, we will give you a brief overview of how NMUI works and share our experience of revamping our Designers Hub screen using it.
Our framework enables us to specify our screen layouts using a common declarative language that can be understood by everyone - in this case JSON. Based on that declaration, it converts that definition of components into native code, rendering our design system components. With this, the designers can see the screen rendered on a real device just like how it will be on the app. It also allows them to handoff the full UI specification to engineers, who can then focus on things like business logic, networking or performance, instead of having to focus a lot on UI for every single feature, while also promoting collaboration between both teams.

The Designers Hub screen is an integral part of our user's journeys because Farfetch offers products from thousands of designers and navigating through all of them can be overwhelming for our users. Taking advantage of the user’s preferences and their past journeys, the Designers Hub functions as a tailored shortlist of the designers the user is most interested in. They can see their favourite designers, be inspired to see our designer recommendations (tailored by the customer's usage) and also still access all of the designers we have on our platform.
For the Designers Hub, we based most of the declaration of how the screen was to be laid out on a JSON configuration file. This file contains all the components we want to show on the screen and the individual configurations for each one.
Initially, we wanted the JSON file to represent the whole screen structure as much as possible, but we found that this approach was generating unnecessary complexity (there are a lot of rules about which things are shown) so we ended up using the JSON as a basic template for the screen and building the UI from there in code. NMUI is very flexible and lets you take a mix and match approach.

Getting a working prototype for our screen was as simple as following these steps:
- Creating new UI components inside the framework (if they don’t already exist).
- Adding an NMUI JSON configuration file to our project.
- Loading NMUI and creating a view for it inside our ViewController.

Additionally, if your screen has a lot of dynamic data or if you need to bind some actions to your UI, you are provided with some delegate methods which will notify you every time something relevant happens (e.g. a component being loaded or shown). In these methods, you can provide your dynamic data for the screen (e.g. Designers we want to show) or you can perform bindings, so that you can be notified when user interactions occur. All in all, it's much simpler than using UITableViews or UICollectionsViews and the whole architecture promotes a clear separation of concerns between your UI and business logic.
As this was the first NMUI implementation for our team, we had some challenges to overcome:
Flexible reusable components
We want our NMUI Components to be as reusable and flexible as possible, so we can reuse them for new features. Any changes to an existing component must be carefully considered with the design team in order to analyze the potential impact in screens where it is already in use. Although we already had these priorities in mind with our previous approach, we found that we now had to take extra steps to ensure that our components will be useful in the future. Although this is a challenge, it helps us to meet our goals of always maintaining coherent and consistent design standards.
Challenges implementing some native features
While we can streamline our development process in most critical pain points, in some cases, the usage of NMUI creates some extra barriers for us. Some features like swipe actions are not as straightforward to implement. In this case, it would require enabling support at the framework level and would have been trivial to implement had we used a vanilla UITableView.
Communication between designers and developers
The handoff between designers and developers is not just handing over a Sketch mockup. Ideally, the designers provide us with a JSON file that will render the screen exactly how it will on the app. This is where NMUI really shines, but in this phase of transition where lots of new components were being created, it was not always possible.
As alluded to previously, creating fully generic components while adhering to new design standards is not an easy task. The definition of new components requires a lot of communication and guidelines between Design and Engineering so that these can be configurable, adaptable and reusable in the future.
We believe that fostering communication is essential (even though it can sometimes be challenging) and that it helps us all to do better work.
While we faced some initial growing pains and challenges, we feel that the benefits of using NMUI make all of this worthwhile. Here are some those benefits:
Stricter design system
The use of NMUI makes it easier for the designers to identify which components we already have implemented and also exactly what customizations they can make. For this purpose, we have a sample app for prototyping where anyone can provide a JSON, configure it and have real-time feedback about exactly how it will like inside our live app. Our designers also have access to this app and it enables them to make pixel-perfect adaptive layouts that we can import into any app.
This approach helps maintain consistency throughout the app and makes it a lot easier to identify if we need to make new components or not. With our old approach (due to the fact that our project and team have considerable scale) we found that sometimes it was hard to track what UI components we already had and what configurations they supported. Centralizing all this into our UI framework, which designers also use, makes it much easier to adapt our design system. The path of least resistance is to reuse an existing component, if you need to create a new one there is a process you have to go through to ensure that it meets a need and fits within our design system, as opposed to just creating a new one which will only ever be used for a specific screen. This friction is intended, it promotes reusability and therefore consistency throughout the App. It is easier to make atomic extensible elements, as opposed to creating different versions of the same thing.
Communication is also improved because the terminology is shared amongst all teams and also because there is no siloing of tasks, everyone has to collaborate and communicate efficiently in order to create the components.
We feel this is one of the main selling points of NMUI and was one of our goals for implementing it.
Ease of propagation of functionality between components
With our framework, features such as Dynamic type and Accessibility are first-class citizens. Implementing them is a breeze and requires very little code. For Dynamic type, you only need to make sure that your component has a dynamic height and NMUI takes care of everything else for you. Voice over support is enabled by default and for simple things, like labels and buttons, no code is necessary (the implementation is at the component level). If you have more complex actions, like our favourite/unfavourite designer feature, the implementation is very straightforward and doesn’t involve many lines of code.
Our whole team (Product, Design and Engineering) have these concepts in mind from the component ideation stage and they are also required when we are delivering new components. Once this work is done, the components will support these features with minimal to no extra code necessary. As an example, for the Designers Hub, we integrated a skeleton (loading) state and a "sticky header” features for components. This feature is usable in any of our existing and future components.
Handoff between designers and developers
I know this was previously stated as a challenge, but for the components we already had, the handoff was seamless. It was just a matter of using the JSON configuration provided by the design team onto the app. In terms of UI, everything was already validated by the design team on the NMUI sample app so this process was much smoother for everyone involved. This greatly improves the speed of the development team, the UI implementation of any screen that reuses existing components is almost instant!


We feel this is another place where NMUI really shines, the developer can focus more on business logic and creating a performant and consistent UX as opposed to pushing pixels. Gone are the days of the design team asking for small adjustments for a specific device, because now they have the tools to implement and validate with real-time feedback before handing off to developers.
All in all, we think the foundation we are building for NMUI will streamline our design/development handoff process and enable both teams to focus more on the details that are more relevant to them while helping to maintain a consistent design system throughout our applications. We also believe it will promote healthy collaboration between both disciplines and enable us to leverage their expertise more.
The Designers Hub screen showed us the processes that we need to improve in order to enable its full capabilities but it also validated the NMUI framework concept and proved that we can use it to build powerful, delightful native UI and UX, with all our attention to detail.
Personally, I really enjoyed the experience of using and contributing to NMUI for this screen and I look forward to seeing it evolve in the future!