Making sense of web app debug logs on multiple Android and iOS devices

If you’ve ever needed to debug Cordova web apps on iOS and Android it can be quite an awful experience for a web developer. Since working on Postcard web app I’ve found a couple of neat tips to help make sense of those noisy debug logs.

From localhost to native land

Designing and developing in localhost is familiar territory to web developers and so it makes sense to try and get as much work done there as possible. But when you need to use the physical hardware features of a mobile platform the only way to see if things really work is to go native.

For Cordova app development on Android there are a few ways to debug web apps but usually it’s a case of cordova build android then cordova run android --device --debug. Then if you have setup Android SDK’s PATH environment var you can run monitor in command line to open up the Android Device Monitor app to see all the logs.

AndroidDeviceMonitor

For Cordova app development on iOS it’s usually cordova build ios in Terminal and then you just open the project in Xcode to debug the app.

XcodeLogs

Both these options allow you to run and debug multiple devices although you have to tab or switch views to see the other devices logs. Also Android logs are so noisy it’s almost impossible to spot the stuff you want to look at. Ideally I would like to look at all logs at the same time and dial in on the stuff I’m really interested in.

While developing the Postcard app I mocked up the UX flow to perform an Identity Exchange with two devices using our peer to peer Thali Cordova plugin for iOS and Android. Needless to say the Android logs got very busy and I also wanted to be able to get the logs of iOS devices outside of Xcode sessions. Thankfully there are a couple of better ways to debug multiple Android and iOS devices from one Mac –

Debugging Cordova web apps on multiple Android devices using adb and logcat filtering

List android devices attached:

Because I have two android devices attached I want to be able to target both from command line.

Once Cordova has installed the app on device you can use logcat to see the logs in Terminal. However with multiple devices you want to use adb -s to target a device and then use logcat -s to filter out all the noise! With the Postcard app we are using jxcore to run Node.js on mobile so I used ‘jxcore-log:*’ as my filter.

In another Terminal tab or split window in iTerm.

logcat-jxcore

Now that’s much cleaner and stuff doesn’t scroll faster than you can actually read! 😉

Assuming the Android device is already developer enabled you can also inspect the web view and javascript console logs in Chrome: chrome://inspect/#devices

Debugging Cordova web apps on multiple iOS devices using iOS Console

With iOS all you need to do is attach your devices and download iOS Console which is a handy freeware app to view iOS logs on a Mac with filtering. With our iOS Postcard app I have set the filter to ‘jxcore’.

iOSConsole-logs

iOS Console doesn’t need Xcode running and the logs are a lot cleaner than the default Console app.

Also you can inspect the web view and javascript console in Safari once the app is running. In Safari browser go to:
Safari > Preferences > Advanced and turn on “Show Develop menu in menu bar” then select:
Safari > Developer > Device Name

Note: If you are using mobile Safari to test your web app instead of Cordova then you will have to enable “Web Inspector” on the iOS device under Settings > Safari > Advanced

Developing a web app that behaves like a native app

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!

Postcard app icon

Icons and splashes generator for Cordova web app

With any project I always like to start with design before I jump into development. Design is a time consuming task but some things can be automated like resizing all those app icons and splashscreens across multiple platforms. I wrote a time saving Ruby script to build app icons and splashscreens for iOS and Android with Cordova’s image filenames and sizes. (Usage and instructions are in the gist)

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.

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!
BrowserSync demo

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.

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.

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.

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

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:

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.

The one problem you still get with iOS UIWebView is that you always get a magnifying glass when doing a long-press and unfortunately there is no simple way of disabling this without hacking UIWebView private APIs.

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.

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.



[46377:7026777] Received memory warning.

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.



Message from debugger: failed to send the k packet

Solution: Keep app awake! In the app delegate enable setIdleTimerDisabled:

iOS Tip: When testing web apps on iOS it can take so long to build and debug on device that the screen locks and the deploy fails. Use the setIdleTimerDisabled to keep the app alive for debugging!


Unity3D Leaderboard demo using BitRave Azure plugin

This is a quick Unity3D game developer tutorial showing how to save, update and query high scores stored in the Cloud using a Mobile Service and the BitRave Azure plugin.

Watch how to create a Leaderboard in the cloud using the Unity3D BitRave plugin.

  1. To save scores in the Leaderboard table you will need to create a Mobile Service.

    If you don’t have an Azure account there is a special Cloud GameDev Offer for game developers.

  2. Get the BitRave plugin with Leaderboard scripts on my GitHub fork.

    There are two new scripts I’ve added for the Leaderboard demo:

    Unity3D BitRave Fork with Leaderboard script demo
  3. Create new Unity project.

    Unity3D BitRave Fork with Leaderboard script demo
  4. Copy contents of the BitRave Universal Plugin Assets folder into your Unity3D project’s Assets folder.

    Unity3D BitRave Fork with Leaderboard script demo
  5. Import JSON.NET dependancy from Unity Asset Store.

    Unity3D BitRave Fork with Leaderboard script demo
  6. Open the TestAzure scene.

    Unity3D BitRave Fork with Leaderboard script demo

    Select Main Camera and remove Script in the Inspector panel. (This will be replaced later.)

    Unity3D BitRave Fork with Leaderboard script demo
  7. Create ‘Leaderboard’ table in Azure Mobile Services.

    Unity3D BitRave Fork with Leaderboard script demo
  8. Open AzureUILeaderboard.cs script and replace Azure Mobile Service connection strings.

    Unity3D BitRave Fork with Leaderboard script demo
  9. Drag & drop AzureUILeaderboard.cs script to attach it to the Main Camera.

    Unity3D BitRave Fork with Leaderboard script demo
  10. Now you’re ready to play in Unity Editor add post some high scores!

    Unity3D BitRave Fork with Leaderboard script demo
    Unity3D BitRave Fork with Leaderboard script demo

In this demo project you can submit new scores, return list of all scores and update them. You can also query to show only high scores or get list of a user’s scores.

Check it out!

Karma Labs on Azure Mobile Services and BitRave plugin in their Unity3D game development.

If you are also looking to handle user identity with Mobile Services and configure build settings for iOS and Android development I touch on this in my first getting started with BitRave Azure plugin tutorial.

Share your Unity3D #GameDev with @deadlyfingers

Unity3D game dev with Azure Mobile Services using BitRave plugin

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.

Watch getting started with Unity BitRave Azure plugin running on iOS and Android

  1. To kick off with create a Mobile Service in Azure management portal. If you don’t have an Azure account yet game developers can register for the Cloud GameDev Offer.

    NB: A Mobile Service will only take a minute to setup and just a couple of minutes more to become active and ready to use.

  2. Download BitRave plugin.

  3. Create new Unity3D project.

  4. Copy BitRave’s AzureMobileServicesUniversalPlugin/Assets into Unity3D project’s ‘Assets’ folder.

  5. Get JSON.NET Unity asset to enable cross platform support.

  6. Open TestAzure Scene.

  7. Open AzureUI.cs script and replace the connection strings with your own Mobile Service URL & API Key.

  8. The BitRave demo uses Authentication with Facebook. You will need to create a Facebook app for your Mobile Service and copy & paste the App Id and App Secret into your Mobile Service’s IDENTITY Facebook section. Then generate the Facebook Access Token under Facebook’s Tools > Access Tokens.

    Copy the Access Token and paste into AzureUI.cs script’s Access Token value.

    NB: Remember to save changes.

  9. In Unity select the Main Camera and remove the Script in the Inspector panel.

    Reattach the AzureUI.cs script. (Drag & drop the script onto the Camera.)

  10. Add the demo TodoItem table (in Azure Mobile Service’s get started section).

  11. Run in Unity Editor and connect to Mobile Service.

    Once logged in you can add a TodoItem.

    You can query or list all items.

    Items can be selected to updated.

  12. In Unity Build Settings switch platform to build for iOS. I’ve selected Development Build and Symlink Unity Libraries for smaller/faster builds.

    To run on the iOS Simulator edit Player Settings and under Target iOS Version menu select Simulator SDK

  13. Open Xcode project to build & run. Rotate iOS simulator to landscape to display UI.

    Connect to Mobile Services by logging in to add some items.

  14. In Unity Build Settings switch platform to build for Android. I’ve selected Development Build and Google Android Project.

    Edit Player Settings to change the Bundle Identifier. (This is in reverse domain name notation – for example net.deadlyfingers.DemoApp)

  15. Import Android project into Android Studio.

    Edit the AndroidManifest.xml and change the installLocation attribute to auto.

    Build & run app. (I find the Nexus 7 tablet API 21 ARM emulator works best with Unity builds.)

    Rotate Android emulator to landscape to display UI.

    Connect to Mobile Services by logging in to add some items.

One more thing to todo!

You can also record the userId by adding one line of code on the server-side.

TodoItem-Insert-userId

Edit TodoItem table Script > Insert

Score bonus points!

Check out my Leaderboard BitRave tutorial showing how to save, update and query high scores stored in the Cloud using a Mobile Service.

Share your Unity3D #GameDev with @deadlyfingers

How to record screen of iPhone, iPad, Android and WindowsPhone device

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.

Camtasia Screen Record Custom Region
Recording simulator window using Custom Region recording in Camtasia.

Windows Phone 8.1 already comes with the screen projection functionality built-in. This makes Windows the easiest platform to record app interaction.

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.

  1. Connect the Phone over USB.
  2. Open Windows Phone Settings and select “Project my screen”.
  3. Install the “Project My Screen App” for Windows 8. Project My Screen app
  4. Tap ‘yes’ when prompt to allow screen projection on WindowsPhone appears.
  5. Allow screen projection

Tip: In the Windows “Project My Screen” application press ‘F‘ key to toggle fullscreen mode and ‘B‘ key to hide the phone background chrome.

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.

  1. Connect PC/Mac and iPhone/iPad to the same wifi network.
  2. Launch Reflector application.
  3. 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:

  1. 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
  2. Record screen using adb shell. NB: Requires Android 4.4 KitKat (API level 19) or above.
    adb shell
    screenrecord /sdcard/recording.mp4
  3. Stop recording (Control+C) and exit shell.
    exit
  4. Copy screen recording from device’s /sdcard onto PC/Mac
    adb pull /sdcard/recording.mp4
  5. Move / rename recording
    mv recording.mp4 ~/Desktop/

Recording screen of Galaxy Note 3

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.

Send GCM Push Notifications using Azure Mobile Services

  • Difficulty Rating***
  • Time Estimate15 minutes

Tutorial requirements:


  1. First install Google Play Services package in the Android SDK Manager.

    NB: If using an Android Virtual Device then ensure your Target is set to Google APIs to allow Push Notifications to work.

  2. Create a new project in Google Developers Console.

    Turn on Google Cloud Messaging for Android.

    Create a new Public API access key.

    Create a new Server key.


  3. Copy the public API key

    Paste API key into Mobile Service’s Push > Google Cloud Messaging settings

    Save changes.

  4. Copy google-play-services.jar (from Android SDK libs) and notifications.jar (from Azure Mobiles Services SDK for Android) into the Android project’s libs folder.

  5. Add Push Notification permissions to the project’s AndroidManifest.xml.

    NB: Replace all occurrences of **my_app_package** with the manifest’s package name attribute.

    Add the receiver block just before the application closing tag.
    eg. … </application>

    NB: Replace **my_app_package** with the manifest’s package name attribute.

    NB: If you get a red text error on receiver notifications.NotificationsBroadcastReceiver then add dependencies to the build.gradle file and sync project libraries.

  6. Copy Google Project Number in overview section.

    Paste value into ToDoActivity.java as a String constant.

    In the onCreate method of ToDoActivity.java add a Notifications Manager handler.

  7. Create a Channel class

  8. Create MyPushNotificationsHandler class

    Tip: To auto import classes in Android Studio enable Add umabiguous imports on the fly

  9. Create new Channel table in Azure Mobile Services.

  10. Edit TodoItem table Script > Insert


    This will send a push notification upon successful insert of a Todo item.

  11. Edit Channel table Script > Insert


    This will prevent duplicate registrations of user and device handles.

  12. In the app add a Todo item to trigger a Push Notification

    The Push Notification will appear with the Todo item text.

That’s all there is to it! If you wanted to take it to the next level you could use this backend Mobile Service and roll it out across other platforms like Windows Store, Windows Phone, iOS, or use cross platform tools like Xamerin or Phonegap.

For latest platform support, how to connect to other identities and push notification services check out the Azure online docs.

Setup Mobile Service table permissions and authentication

  • Difficulty Rating**
  • Time Estimate15 minutes

Tutorial requirements:


This article builds on top of the previous tutorial where an Android Todo app was created with Azure Mobile Services. However most steps can be adapted for any Mobile Services Android app.

  1. Edit TodoItem table insert permissions to Only Authenticated Users.

  2. Create twitter app.

    Copy Mobile Service URL from Azure Mobile Service Dashboard

    Paste the Azure Mobile Service URL into Twitter app’s Website and Callback URL fields and save. Then in Settings tab tick the ‘Allow this application to be used Sign in with Twitter’ checkbox.

  3. In Twitter app’s API Keys tab copy the API key & API secret.

    And paste them into Identity > Twitter settings.

  4. In Android Studio ToDoActivity cut the code block under the new Mobile Service client.

    And paste into a new method createTable().

  5. Replace the code block with a new authenticate() method.

    Then build and run

  6. Sign-in with Twitter.

  7. You can record the userId on the server-side. Edit table Script > Insert

  8. Add another Todo item in the app.

    Refresh the ToDoItem table to see the new item with userId.

  9. Now change Script > Read so app shows only the authenticated user’s items.

  10. Refresh app to see changes.

    The list should only show ToDo items that belong to that user now.

Impressive — with just a couple of lines of code the app is updated to enable user authentication and handle identity requests.

Azure Mobile Services also allows you to send Push Notifications which is covered in the next tutorial.

Create a Mobile Service in Azure

  • Difficulty Rating*
  • Time Estimate10 minutes

Tutorial requirements:


  1. Create a new Mobile Service in Azure.



    The wizard will take you through this process in a couple of steps. Once the mobile service is created it will only take a couple of minutes to start up before its ready to use.

  2. Create Todo Table.

  3. Download Todo App.

  4. Extract the Eclipse project archive and Import Project in Android Studio.


    The project may take a while to import while Gradle syncs the libraries.

  5. Build and run!

  6. Add ToDo item and then browse the TodoItem Table in Azure Mobile Services.


Cool – you just built an Android app with a cloud backend in minutes!

Now you can add table permissions and setup authentication using Twitter in the next tutorial.

Create an Android app with a cloud backend in minutes

These days it’s probably a good idea to have cloud backend for your apps. There are a greater number of connected devices in comparison to individuals, which means your apps may be expected to work as well as sync across multiple platforms as a rule.

The number of connected devices more than number of people.

The number of connected devices is more than number of people since 2008. Source: Cisco

This tutorial will show you how to create a cloud backend for an Android app, but the bigger picture would be the ability to roll this out to the other platforms as well. The idea that all the connected devices of an individual user (perhaps an iPhone, iPad, WindowsPhone and Windows device) could all tap into the same shared resources and server-side business logic in the cloud. Of course managing a cloud infrastructure or server isn’t something that most app developers want to get burdened with, never mind the cost and time implications. Azure Mobile Services takes care of all that, enabling developers to focus on developing the app – making the best possible user experience.

I have arranged this tutorial as a three part series. Each part features a 10-15 minute video screencast to allow inclusion of additional titbits that I hope will prove useful. Please note these tutorials are recorded using Android Studio on a Mac, so bear in mind that some steps may differ slightly if you are using Android Studio for Windows or Eclipse.

How to create an Android app using Azure Mobile Services tutorial parts:

  1. Create Mobile Service in Azure
  2. Setup database table permissions and Twitter authentication
  3. Send push notifications with Google Cloud Messenger (GCM)