This article is contributed. See the original author and article here.
Authors: Lukas Cerny, Rui Zhou, Zhongyuan Li, Karish Singh, Denoy Hossain, Xin Deik Goh
Sponsor: Prof. Joseph Connor
Supervisors: Dr. Dean Mohamedally, Dr. Emmanuel Letier, UCL
ImagineThis is a multi-functional platform on Azure for building, testing and running early-stage designs of applications without the need to write any code. It converts a wireframe sketch design from Figma, into code and publishes it in a way that anyone can run the generated app on their iOS or Android devices merely by scanning a unique QR-code. Version 1 was developed by a group of UCL students as a part of summer 2020 UCL IXN project. We have substantially expanded the capabilities with Version 2 with our Azure implementation.
Demo
Introduction
Early-stage application prototype testing is one of the most important phases of software product development. It can reveal flawed assumptions or incorrect requirements and thus save lots of time and money. App designers working with clinical trusts in the NHS are currently facing a problem where it takes much longer to develop healthcare application than wanted. This is especially important in the healthcare sector where shorter product delivery times can lead to more lives being improved or potentially saved.
One of the causes for such delays is a general lack of developers and software engineers at the NHS. Another one is length of tender processes in which external companies demonstrate their proposals for apps and the NHS has to decide which one to go with. To reduce the overall development time, our partners within the NHS commissioned a tool to be enable rapid design prototypes to generate app templates on mobile devices.
Our solution
ImagineThis version 2 is a multi-functional platform for building and testing early-stage designs of applications. It works with a well-known commercial platform Figma through which users create designs of applications. Using Figma’s API, ImagineThis fetches a JSON file of a particular design the user wishes to build and converts it into React-Native source code. React-Native was chosen due to its cross-platform nature, meaning it can run on both iOS and Android devices. The auto-generated codebase contains all necessary files and components which developers can download as a ZIP file, so that they continue working on it.
This code generation feature can save lots of time for developers as they no longer need to setup the whole codebase structure nor write code from scratch.
On top of that, after the code generation succeeds, ImagineThis publishes the app to a platform called Expo: an external commercial system that simplifies application development process. Expo has a mobile client Expo Go through which developers can easily test apps on their phones. We use Expo exactly for this purpose.
Furthermore, after ImagineThis publishes the generated source code to Expo, it displays a project unique QR-code that users can scan in order to open the Expo Go client where they run the published application directly on their phone, without any need for app stores or installations. This whole process works automatically and seamlessly, therefore building and running an app on user’s phone is just a matter of few clicks and no need for any coding at all! Figure 2 below graphically illustrates this process.
Finally, after users test the application, they can post feedback to ImagineThis and upvote or downvote feedback from other users. This information is incredibly useful for designers to make adjustments and for clinical study staff in the NHS to understand the opinion of end-users.
Architecture
We decided that a classic 3-tier layered architecture on Azure is the most suitable one that meets our requirements. Firstly, there is a web user interface, the front-end layer, implemented with ReactJS and using React-Hooks for global state management. Secondly, there is back-end, the busines logic layer, which performs the conversion of Figma design to React-Native source code and also communicates with the database.
The back-end is a RESTful API written in Java and using Spring Boot framework. Also, we use various state-of-the-art technologies like MyBatis for mapping database to Java objects, Swagger for testing and documenting the RESTful API or Jacoco for analysing the test suite code coverage that we aim to get above 50%. We even integrated Jacoco into our continuous integration (CI) pipeline, so that we can view the code coverage metric continuously and in real-time.
Lastly, there is PostgreSQL database in the persistence layer serving as the data storage for feedback and project data.
Code conversion
Although the code conversion functionality was already implemented by the previous group in ImagineThis V1, we’ll briefly describe how that works. ImagineThis’ back-end queries the Figma API for a large JSON file representing the whole design. This, of course, requires authentication, so users have to authenticate themselves either by entering their Figma account token into ImagineThis, or through Oauth 2.0 protocol.
The Figma design has to obey certain rules (e.g. naming conventions), so that ImagineThis can interpret what individual components are; for example, we want to differentiate a button from an input field. Using these rules, ImagineThis parses the JSON file with Java gson deserialization tool and produces a tree-like object with a list of FigmaComponents. This is our abstract representation of the Figma design. With 1-to-1 relationship we map each of these FigmaComponents into ReactComponents, which are responsible for producing the application code. We consciously made the distinction between these, in order to separate concerns and responsibilities, to improve code’s testability and also to make the system extensible to new languages (like Kotlin) or design platforms.
Docker containers
We decided to use Docker containers for running each of the layers mentioned previously. Docker gave us many valuable advantages. Firstly, it vastly simplified the deployment. Since we are using docker-compose functionality to orchestrate multiple containers, deployment is just a matter of running few shell commands.
Secondly, Docker increases flexibility as it works across different operating systems and environments. Deployment was practically the same whether we ran the whole system locally on our laptops, or on the Azure production server. It will be the same even on other cloud providers as well.
Thirdly, Docker is resource efficient, as we can run all layers on just one virtual machine (VM). This is how we cut down client’s costs by half, since instead of running 2 VMs separately, one for the front-end and the other for the back-end, we run all layers on just one VM. Consequently, the whole system can easily scale horizontally merely by adding extra containers and VMs.
Finally, we used Docker containers to facilitate the publishing process. The next section describes how this works.
Figure 5: Architecture of Azure based ImagineThis V2 system. 3-tier architecture layers on the left-hand side, and publishing job containers on the right.
Publishing process
As already described, after ImagineThis generates the source code, it builds and publishes the app to Expo. The publishing process takes quite a while. Also, the only available API Expo supports is the Expo CLI. Therefore, we needed a way how to run this asynchronously and in an environment that has access to shell.
Rather than using our back-end Java server for this, we decided that spinning up a new Docker container that performs the job will be a better solution. We setup an image with a Dockerfile, which runs a shell script that builds and publishes the generated app. The advantages of using Docker containers include the ability for jobs to run simultaneously and in isolation alongside the architecture being easily scalable. Moreover, the shell script that those containers run is actually trivial, we just copy generates files from a volume and run Expo command:
# Copy generated app source code to this directory
# Note: /usr/src/app is volume shared with backend container which generates code there
cp -r /usr/src/app/$PROJECT_ID/* .
expo publish
Having said that, we are using Docker volume for data communication across different containers. As Figure 5 shows, the back-end container writes generated React-Native source code files into the volume. On the other hand, Expo publishing containers mount that volume and copy files into its own directory (as showed in the code snippet). From there they run the Expo command to build and publish the app.
Furthermore, we are using Docker as a synchronization primitive. Since containers must have unique names, we are naming these job containers as imaginethis-expo-{project-id} (in Figure 5 just expo-{project-id} for brevity). Only one container with such name can run and thus Docker will prevent the back-end from triggering another job that publishes the same project.
Future work
There are several directions in which we see ImagineThis could continue to grow. One is to improve the code generation process by using multi-threading. Currently the conversion from a Figma design into React-Native code runs sequentially in a single thread. But wireframes (application pages) could be converted in parallel which would vastly improve the conversion time.
Implementing an authentication system will be an essential improvement. Users will have to sign up and log into ImagineThis, which will let them access only those projects they are authorised for (currently all users can access all projects). Finally, we want to use Azure Kubernetes as the orchestration engine for Docker containers.
GitHub Repo
For anyone interested, our code is available publicly on Github!
Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.
Recent Comments