28 October 2016, by Chris Arnott
If you want to write a phone app, and want it to run on multiple platforms, but don’t want to spend large amounts of time maintaining two code bases, then there are several solutions that allow writing one app, and deploying it to several platforms.
These multi-platform apps work by running a mini website on a phone, which is accessed via a web view, which is how the app appears native.
In this post, we’ll discuss several different approaches to writing a multi-platform app, and have a look which situations you should choose each option.
3 February 2016, by James Griffiths
Here at Softwire, we’ve been busy building a mobile app for a chain of health clubs, and this is the final post in a four-part series about our experience and what we’ve learned.
We’ve chosen to build the app using Apache Cordova, so our code can easily run on both iOS and Android platforms. Take a look at the first post to read about what Cordova is, the second to see some of the practices we use to make Cordova feel as app-like as possible, and the third to see how we keep our transitions smooth in KnockoutJS.
In the nearly 16 years we’ve been around, we’ve supported many customers’ projects – including maintaining and supporting this customer’s pre-existing web application, which allows users to book exercise classes and tennis courts. All this has given us great insights into what makes software easy or difficult to maintain.
One of the major causes of difficulties in the old website, and elsewhere, is unnecessary state.
As you browse the website, the site builds up a large collection of state about your visit, which it then uses to work out what should be displayed on each page. This means if we find a bug it can be quite time-consuming to work out where each piece of state was originally set, and how the various pieces of state interact.
For the mobile app, we definitely didn’t want to repeat this mistake. We decided to declare war on state and to focus within this project on making the app as stateless as possible, so it was easy to reason about, understand, and maintain in future.
What did this mean for us?
There’s an API for that
To start with, we decided that the app should communicate with the back-end booking system using a stateless RESTful API.
Each API request that the app makes contains all information that the API needs to complete the request, meaning that the API doesn’t need to remember details of any previous requests.
This makes testing significantly easier, as the back-end API can now be tested separately from the app. Debugging is also much easier, as the isolated requests make it clear whether a bug is caused by the app, or the API.
Let’s go on a journey
The design of the UI in our app is reasonably complex; it’s built from hundreds of moving parts, each of which can change depending on the state of the user’s booking.
To reduce the amount of common state that we have to deal with we’ve divided the UI of our app into 3 ‘journeys’, each of 4 separate pages. Each journey is responsible for the flow between various pages, and the interactions between the pages required to make this work. Each page is then responsible for the details of a specific part of that journey.
These are represented by ‘journey’ and ‘page’ view-model objects within our code; any state relating to how the journey and pages are displayed is stored on these objects. Each time the user starts a journey, we create a new instance of the journey and page objects, and when the user leaves a journey, we destroy the journey and page objects. This ensures the journey and pages never contain state left over from a previous visit.
On a strictly need-to-know basis
In the old website a great deal of information was passed between pages, including large, complex object models, dramatically increasing the complexity of the codebase, and making it hard to tell where any information came from.
For the mobile app we have taken the opposite approach and pass around as little information between pages as possible, usually just a single ID, e.g. the ID of the exercise class being booked, or the ID of the booking.
If it breaks, turn it off and on again
Within our app we’re using quite a few fancy UI widgets. One of them – a swipeable carousel of dates – doesn’t play very nicely with Knockout: every time we change the list of available dates, the widget re-draws the carousel vertically, rather than horizontally! Clearly this widget isn’t stateless, sadly, as it’s appearance isn’t just a function of its inputs, but is also affected by its previous state.
We spent a while trying to fix this in the widget itself, but to no avail. Fortunately, we then thought of another approach: instead of changing the list of dates, simple destroy the old widget and create a new instance with the new set of dates, which worked a treat.
This change essentially makes the widget stateless, from our point of view, by destroying and rebuilding it at any time when the state might change, so that the widget’s appearance is instead based only on its current inputs. When statelessness gets difficult frequently and pre-emptively “turning it off and on again” can actually get you remarkably close!
21 December 2015, by James Griffiths
Here at Softwire, we’ve been busy building a mobile app for a chain of health clubs, and this is the second post in a four-part series about our experience and what we’ve learned. Watch this space for the next instalment, or follow us on twitter for updates!
We’ve chosen to build the app using Apache Cordova, so our code can easily run on both iOS and Android platforms.
For the iOS app to be available on the App Store it needs to be approved by Apple. One of Apple’s requirements that is particularly relevant for Cordova apps is that the app “feels like an app, not like a website”.
What does this mean for us? There are a lot of components to this, but in this post I want to look at how it’s affected our approach to client-server interaction.
We’re lucky to have some really nice designs for the app, and we wanted the entire UI to live up to these.
To keep this user experience really smooth one thing we really have to ensure is that we don’t ever show the user an ugly 404 page.
On a regular website, a user moves from one page to another. Each page is loaded individually from the server and contains the data they have asked for, as well as the code needed to take them to other pages.
This wasn’t an option for us. Our app users might be on the move, underground or have a slow data connection. If we built the application extremely minimally as a wrapper around a traditional server-hosted application then we’d be making these page requests in an environment where they might fail. We can’t risk showing them an half-loaded page or, even worse, a 404.
Load data, not code
To solve this, we’ve built the application as a single-page website. All the code is bundled into the initial download – that way, all our pages load instantly, without having to wait for any code to be downloaded. This approach is an important part of good Cordova development, and helps solve the error handling issue above and reduce latency for users to keep the app feeling snappy.
The only communication we have with our servers is to send and receive data (rather than code). We have a RESTful API that manages all our operations, like loading class timetables, making bookings and getting club opening hours.
If any of these API requests fail we can show the user a pretty error message, and allow them to retry, without the app looking broken.
The app looks beautiful so we want it all to perform well on the phone. That includes loading pages, but we also want scrolling, swiping and transitions to all be smooth, and to avoid the screen juddering.
In the next post we’ll look at how we achieved this. Keep an eye on our blog for the next edition, or follow us on twitter for updates.
16 December 2015, by James Griffiths
Here at Softwire, we’ve been busy building a mobile app for a chain of health clubs, and this is the first post in a four-part series about our experience and what we’ve learned. Watch this space for the next instalment, or follow us on twitter for updates!
We were recently asked by a large chain of health clubs to build an app for both iOS and Android platforms. We chose to build the app using Apache Cordova, rather than writing separate native applications. Why did we choose Cordova, and how do you get started with it on a new project?
The problem with native apps
At Softwire, we’re used to building native mobile phone apps, but building native apps comes with a number of difficulties:
- Each platform requires you to learn and use a specific programming language, development environment and set of libraries.
- You have to maintain a separate codebase for each platform and keep the code in sync between platforms.
- Each platform has its own quirks and bugs will typically be different in each platform.
All of this makes native development potentially more expensive and risky, and we’ve been interested in investigating other approaches for a while.
What’s the alternative?
13 November 2013, by David Giles
A bunch of us from the Bristol office went to the second BrisTech, a new tech meet up in Bristol. As well as free beer and pizza there were a couple of talks, including one by our very own Tim Perry.
The first talk was on cross platform mobile development, from HTML 5 based frameworks to solutions like Adobe Air. The talk was very good, and centred on Property Cross an example application implemented in a variety of frameworks. In essence these save time, but there is still effort in making the apps behave as you’d expect from the platform. On top of that supporting Windows Phone is generally far more difficult as it both has worse support amongst the frameworks, but also making the apps feel native requires a totally different design.
As a bonus the speaker Colin Eberhardt did a second, short presentation “What’s Wrong With Green“, about the startling lack of green in App Store screen shots, and other useful results of data mining Apple.
17 April 2013, by Anna Mulholland
We found these videos on design for mobile platforms useful:
- Buttons Are a Hack! (Josh Clark) – this video suggests that designing for touch might take a bit of a rethink.
- Cage Match: Mobile Web vs Native Apps (Josh Clark) – discusses when you should choose mobile web apps and when you should choose native apps.
- Slide to Unlock part 1 and part 2 (Sarah Parmenter) – gives tips for how to approach designing the UI for an iOS app.
22 January 2013, by Richard Meal
If you are testing a webpage you have developed for BlackBerry mobiles, then the BlackBerry website is a useful place to visit as it has simulators of all their devices available to download. Once installed, the simulators that are running OS6 or higher can be used to view your webpage in their browser straight away. To get the browser working on OS5 simulators or older, the BlackBerry Mobile Data Service simulator (MDS) needs to be installed and run, instructions for doing this on Windows 7 x64 can be found in this helpful blog post here (this is a link to the Google cache version as the site is down at the time of writing).
The most useful thing I have found is, since BlackBerry OS7, there is now a way to debug webpages, which is very useful as the BlackBerry browser has a lot of quirks, despite being Webkit based since OS6. The following can be done in either the simulator or on an actual device:
First of all you need to go to the Browser Options and ensure ‘Enable Developer Tools’ is selected. In the browser you then need to bring up the menu by pressing the BlackBerry button and select Developer Tools > Enable Web Inspector. A popup will then display an IP address and port number.
You can then connect to that IP address using a Webkit based browser on your PC (or a PC on the same network as the device if you aren’t using the simulator) and select the site that is being displayed by the BlackBerry.
Once you have selected the webpage you have access to the full debug tools that are available to Webkit browsers, which are very useful for figuring out why that <select> is appearing twice as large as it is on every other browser.
21 February 2012, by Chris Harris
Every Friday lunchtime at Softwire we all get lured into a meeting room with the promise of free food, and one of our colleagues gives a talk on something they’ve been working on recently.
We filmed my talk on HTML5 and Mobile Dev, so that others can enjoy it too.
22 January 2012, by Hugh Greenish
Last time, we enhanced our Hello World application so that it could interpret our feedback and take some appropriate action. I closed off by declaring it to be “very bad indeed“. This time, we’re going to find out why…
7 January 2012, by Hugh Greenish
In my first post, I wrote a very simple “hello world” application, that displayed an alert box like this:
It’s lovely as far as it goes, but you were to install that application on your phone, you would no doubt become rapidly disillusioned with it – it may ask how you are, but ideally we’d want something to happen once we press a button. At the moment, all that would happen is that the popup would disappear, and you’d be looking at a white space. Admittedly, this is pretty much how some of the early torch applications worked, but I think we can all agree that we’re not (yet) putting Objective-C to its best use.