Hosted by Microsoft Azure

Menu

Like many developers out there I started out coding for the web. So you might think it would be easier to develop a web app than a native app, right? The short answer is no… but web app development is getting better and the performance gap is closing.

Thoughts on web app vs native app development

Delivering a world-class UX is the main reason to opt for native development. Web app performance has quite some way to go especially on the vast majority of low spec devices. For example even if you get your web app running at a buttery smooth 60fps in iOS Safari, it doesn’t automatically mean you get that sort of performance in an app’s UIWebView.

iOS Tip: Don’t be content testing any web app or web UI framework in Safari and think that it works. A real web app development test is only done by running it inside an embedded WebView.

What you have to be careful off is getting sucked into some web app framework because you can get some decent results pretty quickly, but as soon as you add a little more complexity things can start to break and the speed of development will slow as a result. Whereas while native development might take longer to learn initially, after that you can start building some pretty slick apps just using the standard suite of UI components provided.

Ultimately things are getting better for web app development but probably not enough as to make native app developers want to consider switching. But with all the modern browser javascript speed optimisations and mobile devices becoming ever more powerful it’s worth considering a web app where the ability to share code is most important. After all who wouldn’t rather develop code once that works across mobile and desktop and leverages the extensive web developer knowledge base? So the compelling reason to build a web app is that your code should run on any screen that runs a modern browser.

Postcard app

I’ve been involved with developing the Postcard app which is a web app for demoing a peer to peer web experience using the Thali Cordova plugin. Throughout the design, development and build process of this web app I’ve encountered a number of issues or pain points and thought it would be good to share the golden nuggets I’ve learnt while trying to develop a web app that behaves like a native app!

Designing a web app across different screens – live!

Many web apps take advantage of node and there is a great module for designers called BrowserSync.

Shell

1

npm install-gbrowser-sync

BrowserSync allows you live preview all your design or code changes across multiple screens. That means you can test your web app in real-time on any browser on Mac or Windows as well as hook up the web app on iPhone, iPad or Android. Also when you interact on one screen for example following a link or scrolling the page this automatically updates everywhere else. This is a must have for any responsive design or adaptive design work!

Polymer 1.0 – a UI kit for web apps

For the UI design side of things I choose Polymer 1.0 due to it’s host of web app elements inspired by a native app’s UI kit. Initially I didn’t like all the custom element names, as this reminded of an Angular wild west of element names but you can quickly learn the Polymer core elements and view the documentation and source behind them. Also there is a benefit to this as it prevents the usual ‘div nest of inception’ meaning that an HTML layout can be understood at a glance.

Getting started developing with Polymer

The trickiest thing is actually getting all the Polymer elements you need to use as these all come separately which of course makes sense later for production. But do yourself a favour and just install all the paper, iron and neon elements for no hassle development.

Shell

1

2

3

bower install--save PolymerElements/paper-elements

bower install--save PolymerElements/iron-elements

bower install--save PolymerElements/neon-animation

Should I use Polymer’s ‘on-click’ or ‘on-tap’ event?

There is a 300ms click delay issue that affects mobile web apps. The good news is that there is a simple fix by using the viewport meta tag with width=device-width property. But the bad news is that this trick only works in Chrome 32+ on Android.

XHTML

1

<meta name="viewport"content="width=device-width, initial-scale=1"/>

Thankfully Polymer tries to handle this issue for you if you use the on-tap event however it doesn’t appear to currently trigger a click on Mac Safari (using an iframe web app). So if desktop Safari compatibility is more important then you may have to stick with the standard on-click event until this is fixed. Or just incase you already use a ‘fast click’ javascript polyfill it may run into issues due to click delay complications with the iOS 8 web view.

Meet ‘iron-list’ – the UITableView for web app

Polymer’s iron-list element is essential for scrolling large amounts of data on mobile devices. It does this by using a virtual list and recycling (20) cells to handle smooth scrolling of 1000s of items. One note of caution is that this runs fine in Safari browser but there is currently a scrolling issue in iOS 8 WebView beyond a certain number of items. If only UIWebView would behave the same as Safari then development would run so much smoother!

Make it feel like a native app – not a web site!

It’s important to make sure things act like an app and not feel like a website thrown inside a Cordova webview. There are a couple of giveaway indicators that can be fixed, although not everything will behave perfectly.

Disable the scrolling bounce effect

While adding the magical web app meta tags will give you full screen control in the browser it doesn’t get rid of the web page scrolling spring effect common with iOS and Mac. Now while the spring effect provides a wonderful UX in a web browsing context – native app’s don’t spring! To disable this unwanted behaviour the first thing to do is to enable the DisallowOverscroll preference in Cordova’s config.xml.

config.xml

XHTML

1

<preference name="DisallowOverscroll"value="true" />

If you are not using Cordova then you can disable the iOS webview scroll:

1

[[webView scrollView]setScrollEnabled:NO];

It’s always a good idea to do a CSS reset on the html,body and then add the following to disable the bounce effect in the browser:

CSS

1

2

3

4

5

6

html,body {

width:100%;

height:100%;

padding:0;

margin:0;

}

CSS

1

2

3

4

5

/* disable webkit bounce effect in the browser */

html,body {

overflow:hidden;

-webkit-overflow-scrolling:touch;

}

Disable select copy/paste

Another annoying web behaviour inherited is that everything is selectable on a web page. Again a useful behaviour in a web browsing context but not so much with a web app. Besides not feeling right there is a UX issue if a user taps the ‘wrong way’ instead of activating a button click as expected they end up in a text selection mode. The easiest workaround is setting user-select to none on the ‘body’. NB: If your web app contains form inputs then you can exclude those inputs using the :not() CSS selector but I find it easier to switch everything off by default.

Prevent scrolling nav bar when editing input

A quirk with web apps on iOS is trying to fix a nav bar so it won’t scroll off the screen when editing an input or textarea that would obscure the soft-keyboard when it pops up. One trick is to position your input as high up the page as possible in order to avoid the issue. But sometimes this isn’t always possible so the other option is to try a hacky workaround discussed on SO which also seems to work pretty well with Polymer:

In Cordova if you want to enable Javascript focus() calls to open the soft-keyboard you can disable the KeyboardDisplayRequiresUserAction preference. Although bear in mind iOS8 now supports focus() calls but I found the input and keyboard can lose connection sometimes.

config.xml

XHTML

1

<preference name="KeyboardDisplayRequiresUserAction"value="false" />

Problems with web app when running as a native iOS app…

I encountered quite a number of problems when running a web app inside the iOS 8 UIWebView. I have listed the main issues below to watch out for with possible workarounds:
[WebActionDisablingCALayerDelegate setBeingRemoved:]: unrecognized selector sent to instance 0x174009d20
*** WebKit discarded an uncaught exception in the webView:willRemoveScrollingLayer:withContentsLayer:forNode: delegate: -[WebActionDisablingCALayerDelegate setBeingRemoved:]: unrecognized selector sent to instance 0x174009d20

Solution: Add body style for -webkit-transform. This WebView bug occurred when animating an element sliding up from the bottom of the page. It caused the animation to jump and skip frames and seemed to trigger memory warnings.

Solution: If you’ve tested for memory leaks then try disabling animations. If this solves the issue then try to optimise your script so that expensive business logic is called only after animations are completed.

To establish peer to peer (p2p) communication on iOS devices there is an API for that known as the Multipeer Connectivity framework. There are a couple of things to bear in mind about this framework:

Discovers and connects with iOS devices but will not discover devices on other platforms like Android

Maximum number of 7 invitees (client peers)

Will raise a prompt for user acceptance of a peer connection request

Intro to Thali project for iOS

Thali is an experimental open source p2p project that promises to enable p2p web to run on mobile devices. This is quite a big undertaking so to make life easier to begin with we can start to look at the iOS to iOS p2p connectivity story which is documented as Thali “Story -1”.
The spec will use the TCP internet standard to transport data across peers therefore all mobile devices will run a Node.js layer. In order to run Node.js on iOS we use a Cordova plugin which runs JXCore. This will then connect with a native TCP bridge which will relay the data over the iOS Multipeer Connectivity framework. The flow is illustrated in the diagram below:

How to build Thali demo for iOS

If you like playing with bleeding edge code you can build the “Story -1” iOS dev branch. (NB: You will need two iOS devices with Bluetooth 4.0 support.)

One of our startups at MS Ventures was looking to use the command line to manage their Azure account on Mac. If you prefer using Mac OS X Terminal or iTerm and have an Azure account then you should check out the Azure CLI tools for Mac.

Just be aware if you use double quotes for --location then you must escape the dollar signs that prefix the params with a backslash (eg. \$). Single quotes don’t require dollar escaping but you may have trouble encapsulating filters with quoted strings hence I have opted for double quotes in these query examples.

Background

When you create an Azure Mobile Service you can download a ToDo sample app to help you get started on a number of platforms including Windows, iOS and Android. There are also cross platform options available with Xamarin or web app development using PhoneGap or HTML/Javascript. Recently I came across a pretty neat Javascript framework called Ember for creating web apps. While you can go ahead and quickly download the Ember Starter Kit to try out some of the introductory snippets listed on the Emberjs homepage, the better option for serious development of Ember apps is to use Ember-CLI. The Ember Command Line Interface gets you up and running with a full MVC framework and helps install project dependencies using NPM (Node Package Manager) and Bower. Having just started learning Ember-CLI myself I thought it might be useful to do a getting started tutorial showing how to hook it up with Azure Mobile Services to create a ToDo app with same functionality as the other offerings already available on the Mobile Services quick-start page.

When the app first loads we will need to read a table. In this case we will read the TodoItem table to get a list of TodoItems. When a user needs to add a Todo item we will call the insert method to add an item into a table and update our Ember model for display. The del method will work the same way except the item will be deleted. Finally the update method will be used to save changes to an item, which in this case will be when the TodoItem is completed (stroked out).

Edit models/todo-item.js to handle todo text string and a completed boolean so tasks can be marked off:

models/todo-item.js

JavaScript

1

2

3

4

5

6

7

import DS from'ember-data';

export defaultDS.Model.extend({

// NB: You may not set 'id' as an attribute on your model

text:DS.attr('string'),

completed:DS.attr('boolean')

});

The TodoItem model consists of a string property for the Todo text and a boolean property to say if the Todo item has been completed.

Edit routes/index.js and set model to read TodoItems table:

routes/index.js

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

import Ember from'ember';

export defaultEmber.Route.extend({

model:function(){

varservice=this.get('azureService');

vartable='TodoItem';

console.log("service:"+service);

returnservice.read(table);

}

});

As ember serve auto updates as you save changes you should see some activity in your Browser’s console log.

In the Browser’s console log you might get a refused to connect error “because it violates the following Content Security Policy directive: connect-src ‘self'” that means we need to update our environment config. To fix this add the following contentSecurityPolicy settings to the ENV var in config/environment.js to allow connections to *.azure-mobile.net:

This quick-start tutorial is for Unity3D game developers who would like to get a cloud backend that runs across multiple platforms (including the Unity Editor for quick testing). One of the big advantages for game devs using Unity3D is that it supports so many platforms. It’s fair to say more people own more than one device that connects to the internet and a lot of them can run apps and games. While the platforms and ecosystems may differ as a gamer I would like to play the same game across any device (and on any platform) and expect things to sync. Azure Mobile Services is a ‘Backend as a Service’ which supports multi-platform app development. In Unity the BitRave plugin for Azure Mobile Services is designed to just work on any platform that Unity supports.

Unity game developers looking to publish their games on Windows Store might want to add global/local high-score leaderboards, record user achievements and level progress. For example the ability to save level progress is usually important as users tend to own more than one device and won’t really like the idea of starting over again. With Azure Mobile Services it’s really easy to setup a cloud backend for apps so why not use an Azure Mobile Service to provide a backend for your game? The best part is it will only take a couple of minutes to setup!

If you’ve developed an app you might want to make a promo video showing your app working across devices or multiple screens.

Of course you can record an iOS Simulator, Android Virtual Device, or WindowsPhone emulator easy enough using a screen recording tool like Camtasia but it’s often a bit tricker to record real footage from the device hardware. Also it might be necessary to demonstrate app functionality not supported by a simulator.

How to present and record screen of WindowsPhone device using PC/Mac

On PC you will need Windows 8 installed. On Mac you will need a Bootcamp partition or VMware Fusion Virtual Machine with Windows 8 installed.
The WindowsPhone should have the latest 8.1 update installed.

Unfortunately there is no way to display or record the touch gestures, but this can be dummied using Camtasia mouse effects. Simply ‘mirror’ with the mouse pointer what your other hand does on the device at the same time. Once the screen footage is recorded in Camtasia you can hide the mouse cursor by setting the Cursor Opacity to zero and add a Cursor Highlight effect to simulate the touch input.

How to present and record screen of iPhone/iPad device using PC/Mac

To record an iPhone or iPad you can try out the third party Reflector app. This makes your PC/Mac act as an AirPlay device allowing you to display and record the screen.

Connect PC/Mac and iPhone/iPad to the same wifi network.

Launch Reflector application.

On iOS7 or higher device, swipe up from bottom of screen to open ‘Control Center’ to select the Reflector Airplay device and enable video ‘Mirroring’.

Unfortunately there is no way to display the touch gestures, but this can be dummied using Camtasia mouse effects. Simply ‘mirror’ with the mouse pointer what your other hand does on the device at the same time. Then once your Reflector footage is recorded in Camtasia you can hide the mouse cursor by setting the Cursor Opacity to zero and add a Cursor Highlight effect to simulate the touch input.

How to record screen of Android device using PC/Mac

To record an Android device without rooting your device requires an install of the Android SDK on your PC/Mac. Once your SDK Environment is setup you can run commands in the command prompt / Terminal:

Check Android device is connected to PC/Mac using USB connection. NB: You will have to enable ‘Developer’ mode on your device by tapping Build number seven times (found under Settings > About device). Then enable USB debugging (found under new Developer options settings).adb devices

Unfortunately there is no way to record the touch gestures at the same time using this technique. What you can do is play the original screen recording and mimic the touch gestures over the top while recording using Camtasia.