In this post, I will talk about my approach when building a new mobile app. I focus on how I start by defining a simple user story, understand what the user story is followed by how I can accomplish all that technically. This post focuses on the requirements specification to build an iOS mobile app. The concepts discussed here apply to both iOS and Android and while I have also built a Hybrid Android solution, this document is focused on iOS. The rest of this document is structured as follows
- iOS requirements as mentioned in the assessment document
- Define the user story for the app
- A description of what the app will do
- Technical requirements i.e. what libraries or frameworks can be used to achieve this
- UI design samples for the minimal UI
- Some backend architecture design
- Decisions to adopt this style
- Lastly, Questions i.e. if any aspect of building this is not clear
User story (Agile)
I am an Australian travelling to Europe and while there are many currency converter apps, I want one that converts international money to Australian dollars (AUD).
Understanding the user story
This needs to be a simple app with minimal interface and a clear call to action. It should be something that the user launches and instantly gets what they want i.e. currency conversion from AUD. At its core, It could be a simple app with four UI elements. An interface (dropdown) to select the international currency, textbox to add the value to be converted, another field to show the amount in foreign currency after conversion and maybe a button to trigger the conversion.
Additional features may include,
- the user can backtrack through their currency conversions.
- given the volatility of exchange rates, the user may need to be informed when the exchange rates were last updated.
- the ability to search through available currencies can be a better user experience.
This aims to look at the native iOS app requirements, as examines the underlying technology used to achieve it.
At the highest level would be the ConverterUIViewController, which will have the four (or five) interface elements required for the user to convert foreign currency.
Currency selection: currencySelectorPV (UIPickerView) that shows all the available currency conversion options. The currency options will contain the currency name with the currency symbol in brackets.
Currency input: auInputTF (UITextField) where the user can enter values and a placeholder that says “aud($) I have”. It can delegate events to ConverterUIViewContoller.
Currency Output: foreignOutputTF (UITextField) An uneditable textfield that can display the converted output and it’s placeholder says “foreign currency I get”. It can delegate events to ConverterUIViewController
Convert: triggerBtn (UIButton) whos .touchUpInside event performs the currency conversion and updates theforeignOutputTF.
A inProgIA (UIActivityIndicatorView) over the foreignOutputTF view as some visual feedback to the user while waiting for the currency to be converted.
The elements in the ConverterUIViewController should be arranged via the AutoLayout constraints. The currencySelectorPV should be left aligned and manage the rest of the elements placement via UIStackView.
Nice to have requirements
Haptic feedback, trigger medium (UIImpactFeedbackGenerator.FeedbackStyle.medium) on pressing the triggerBtn and (UIImpactFeedbackGenerator.FeedbackStyle.heavy) on conversion completion.
A previousConversionBtn (UIButton), to backtrack (rewind) through their previous conversions.
Monitor the textFieldDidEndEditing method of the UITextField delegate for currencyInput and convert the value automatically without the triggerBtn button interaction.
A exRateLastUpdatedLbl (UILabel) that’s displayed below the text field, which shows when the exchange rates were last updated.
An extra view with a UITableViewController that shows the conversions they did over the course of using the app.
The text in the app
All written text in the app that comes from backend code would come from Localizable.strings file and be used with NSLocalizedString(key, comment).
The backend involves all the code that would be separated from the UI code and when necessary, the DispatchQueue will be used to update the UI elements. The aim is to keep the code as loosely coupled as possible, in order to ensure it’s reusable across apps, as outlined in the following posts,
The goal of this app is to present the currency conversion information to the user. The user doesn’t need to know where the app gets its data from. Hence, the backend will be built such that, all the user facing UIViewController needs to know is to call class XYZ to get data in native Swift data types. It doesn’t care how or where class XYZ gets the data from. This means we can completely re-write class XYZ without affecting the UIViewContoller as long as the UIViewController gets the data it needs.
Constants.swift: This is a class that would store all static values e.g.
- URL text(String) used to make a network call to fetch some API data
- CGFloat values used to round the UI elements
API.swift: class to fetch the currency data from an external API. Could be further broken down into individual protocols i.e. ExchangeRateAPI protocol and an APIFactory that returns a class that implements the ExchangeRateAPI protocol.
Pre-Process the data and convert it to a format used to populate the currencySelectorPV (UIPickerView) in the UIViewController. It can return the data via either a closure or a protocol. A results Protocol would mean, the ConverterUIViewController can implement it, such that the API class can notify it every time it fetches and updates the values.
Potential libraries to use: SwiftyJSON to parse exchange rate JSON data received from an external API.
Backup.swift: In the likely scenario that the user is in a place where there’s no network connection, the app can benefit from some offline functionality. The first time, the app fetches the currency data from an external API, it can create a local backup of the data using JSONEncoder and read it via JSONDecoder. Therefore, in case the app finds itself in a place with no internet connection, it can resort to the backup data. However, adding this functionality mandates adding the exRateLastUpdatedLbl to the UI to notify the user, they are potentially looking at out of date exchange rate value.
ErrorNotifications.swift: This class contains a set of static methods that can prompt the user in case of an error. For starters, it will use the UIAlertController with the strings and messages coming from
FeedbackHelper.swift: This would be a very simple class that would contain a static method that can be called to trigger haptic feedback when necessary.
I have followed the structure I set out in this post and built both a commercial as well as an open-source version of the currency conversion app. You can find the open-source version on Github and there are 2 separate branches in that repository. The master branch shows an app built using Storyboards and the No Storyboard branch shows the entire UI written in Swift without any storyboards. If you think you can improve the repository somehow, then feel free to do so and I’d be happy to merge your commit.
Additionally, if you would like to try the commercial version of the app, then you can download it here. It has some extra features not present in the open-source version. It’s a bit more fault tolerant with regards to external API calls and it’s got the ability to set favourites for currency conversion.