Category Archives: Technology

Bluetooth Issues on Mavericks

I’ve been having some issues recently with the Bluetooth stack on my Mac acting strangely – causing Bluetooth devices to drop at random times and on occasions, the default mouse and keyboard will stop working even though the machine is running fine. One of the symptoms of this has been the bluetooth preferences pane showing “do not localize” when things become corrupt.

I think (well, I hope) I’ve solved it by performing an SMC and NVRAM reset on the Mac. In case other are seeing similar symptoms, I wanted to share how you do these resets:

SMC Reset: Power down the Mac. Hold down Shift-Control-Option and the power button for a few seconds. Not much will happen. Release all of the keys, and power on normally.

NVRAM Reset: Power down the Mac. Hold Command, P and R down and power on the Mac. The Mac will boot for a few seconds and then reboot. Release all of the keys at this point, and boot normally.

After doing these resets, the Bluetooth stack seems a lot more stable.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

iBeacon Demo at Gartner AADI

Last week, I joined my colleagues from Neudesic at the Gartner AADI (Application Architecture Development & Integration) Summit in Las Vegas. One of the neat things that we were showing was a demo of iBeacon technology, in order to help locate and pinpoint individuals within indoor environments where GPS is not an option. 

To achieve this, we placed a selection of iBeacons around the expo floor (for the iBeacons we used RedBear’s BLE Mini boards, flashed with their iBeacon firmware).

Red Bear BLE Mini

Using Bluetooth LE (a.k.a. Bluetooth Smart), each beacon transmits a unique ID (made up of a major and minor value) on a particular “frequency” (known as a proximity UUID). iBeacon supported mobile applications are then able to “tune in” to this proximity UUID, and based on the power signal for each beacon, determine which area of the floor a user is located closest to.

 

Gartner AADI screenshot

Using this information we created a mobile app that reports on all of the beacons within range on the expo floor. As you can see in the above screenshot, we have 5 iBeacons in range, listed in order of proximity, with an estimated distance calculated by the power signal. As you can likely gather from the data, we were located in the Neudesic booth at the time this screenshot was taken, with the theater, and a selection of other booths in range.

For the show, we developed two versions of the application – one for iOS and one for Android. Both are native mobile applications written using Xamarin, using CLLocationManager for iOS, and Radius Network’s binding for supporting iBeacon on Android. The Radius implementation is especially interesting in that the beacon detection runs as a background service, polling for new iBeacons and raising intents to the UI as necessary (even though Bluetooth LE is a lot more responsible with power vs. regular Bluetooth, we still need to be careful not to kill the battery when using this however).

While this is neat to show just as a mobile application, we wanted to take it one step further and demonstrate how this could be applied in the real world with Neuron, an ESB product from Neudesic. For our expo demo, Neuron provided a backbone infrastructure to allow the mobile app to resolve a name for a beacon ID (think of his like DNS for iBeacons!) and also give a scalable way for users to “check in” to an iBeacon the same way that they would check in via Foursquare or Facebook.

Neuron process flow

As shown above, we developed a process flow using Neuron to accept incoming messages from the mobile application, and then provided logic to determine whether the device was trying to acquire a name for a beacon, or whether the user had walked in to the area of a beacon and wanted to “check in”. The benefit for using Neuron in this situation vs. just propping up a single web service is that our application can now scale to hundreds of thousands of concurrent mobile clients without needing to make any major adjustments on the server-side.

If you were able to stop by the booth at the Gartner summit, I hope you enjoyed the demo and the conversation. If you weren’t able to attend, but would like to know more about how Neudesic is working with various organizations on iBeacon technology and/or Neuron, feel free to drop me a line.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Building a WebRTC Client for Android

*** Update:  As a few readers have pointed out, the libjingle source has now been merged into the main WebRTC branch (https://code.google.com/p/webrtc/source/browse/trunk/talk). As a result, some of the instructions here will need to be adjusted.  I’m going to leave the post as is, but bear this in mind if you are following each of the steps.  Thanks.  ***

If you’ve been following any of the recent developments with WebRTC, you’ll know that the majority of samples and example code available today target the Web browser (typically Chrome or Firefox).  While this is useful to get up to speed, IMO one of the most powerful applications of WebRTC will be for mobile devices.  Despite this, getting WebRTC running on mobile can be somewhat challenging.

While Chrome Beta for Android supports WebRTC, any true mobile client will always need some kind of native application (in order to receive incoming calls in the background).  In this post, I’ll be showing how to walk through the minefield of compiling WebRTC for Android in order to build your own demo app that you can expand upon.

NewImage

Configuring your Build Environment

In order to build Android WebRTC, you are going to need a machine running Linux.  For the purposes of this article, I would recommend some kind of virtual image (VMWare or VirtualBox) running Ubuntu Server 12.04.2 LTS.  When you build your VM image, ensure that you use the 64bit version of Ubuntu, and that you allocate a minimum of 2Gb RAM to the image (any less and you may well see the compiler running out of memory).

After you get your Linux VM up, the first thing is to install the required build tools.  First, the git and subversion clients:

sudo apt-get install git git-svn subversion

Then, you’ll need the Chromium depot tools – these tools are required to build the WebRTC bits, much of which derives from various parts of the Chromium project.  To install:

cd ~
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

After the tools have been brought down, you’ll also need to add them to your path:

echo export PATH="$PATH":`pwd`/depot_tools >> ~/.bashrc

Once this is done, log out and log back in to the server.  From the command line run:

gclient

If all is working, you should see a list of available client commands.  If you see “command not found”, edit the ~/.bashrc file and double check your path is set correctly.

The final part of configuring your build environment involves installing some required libraries and compilers.  To perform this, use the following command:

sudo apt-get install g++ pkg-config gtk+-2.0 libnss3-dev

Once this is complete your machine should be in a position to start pulling down the WebRTC code.

Obtaining libjingle Source Code

In order to build the Android WebRTC client, we are going to pull down and compile the “libjingle” project.  Libjingle is a set of components to interoperate with Google Talk, but also contains (at the time of writing) the most complete and functional Android client.

To pull down the source, follow these instructions:

cd ~
mkdir libjingle
cd libjingle
gclient config http://libjingle.googlecode.com/svn/trunk

After you’ve run the config command you should notice a new file called .gclient in the ~/libjingle directory.  Edit this file (using VIM or nano) and append the following to the end of the file:

target_os=['android','unix']

This will instruct gclient to pull down the required third party libraries and other tools for an Android build of libjingle.

With this file modified, run the following command from the ~/linjingle directory:

gclient sync --nohooks

This will start a large sync of the liblibjingle source code, which will likely take some time.  A great opportunity for a coffee or break at this point!

Installing the Oracle JDK

Before we can compile libjingle, we’ll need to install the Oracle JDK.  Although the majority of the library is native (and uses the Android NDK) this is required to build the JAR and APK file at the end of the build.

To install, go to the Oracle JDK downloads page (http://www.oracle.com/technetwork/java/javase/downloads/index.html) and download the latest JDK 1.6.  Note that JDK 7 will not work and you will get errors later on.  For the purpose of this tutorial I have been using Java SE Development Kit 6u45.

As you are running server, you may need to download the JDK on another machine (where you will need to accept the license agreement) and then copy the .bin file to your Linux server (using either curl, wget, or VMWare shared folders).

Assuming the .bin file is in your home (~) directory, to install the JDK, perform the following:

cd /usr/lib/jvm && sudo /bin/sh ~/jdk-6u45-linux-x64.bin -noregister

This will extract the JDK to the /usr/lib/jvm directory.  After this is complete, we need to set the defaults to use the Oracle VM as opposed to the OpenJDK VM (which is installed by default).

sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_45/bin/javac 50000
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_45/bin/java 50000
sudo update-alternatives --config javac
sudo update-alternatives --config java

Finally, to overcome a small bug in the libjingle gwp compile scripts, we need to create a symbolic link:

cd /usr/lib
ln -s jdk1.6.0_45 java-6-sun

After you’ve done this, run the following command:

java -version

If you see “Java HotSpot build 1.6.0_45″ instead of “OpenJDK”, the correct version of Java is install and you should be in good shape.

Preparing for Compilation

Before we compile, there are a few things that are required.  Firstly, we need to install some 32 bit compatibility libraries so that aapt and other Android compilation tools will function correctly.  To install, run the following command:

sudo apt-get install ia32-libs

Next, edit ~/libjingle/trunk/third_party/webrtc/build/common.gypi

Navigate to the line that contains:

enable_tracing==0

and replace with:

enable_tracing==1

This will prevent the Android client from crashing (when it realizes it doesn’t have a default trace file) and will make debugging the Android application a whole lot easier!

Finally, perform the following commands to complete preparation:

cd ~/libjingle/trunk
./build/install-build-deps-android.sh
. ./build/android/envsetup.sh

This will correctly setup the android dependencies.  Note the leading period on the envsetup script – this is very important as we need the variables to be set for the rest of the session.

Assuming these commands ran without errors, now run:

gclient runhooks

This command will generate the required ninja gwp compilation scripts.  After this, run:

android_gyp

You may get an error indicating that content.gyp could not be found – it is fine to ignore this for now.

Compiling!

If you’ve reached this stage, congratulations!  We can now try to compile!  To do this, run the following command from the ~/libjingle/trunk directory:

ninja -C out/Debug -j 10 AppRTCDemo

This command is instructing the ninja compile tool to generate a debug version of the build, using a maximum of 10 concurrent build threads.

Depending on your machine, compilation will likely take about 10-15 minutes (time for that other coffee!).  Assuming everything went well, you should see some output in the ~/libjingle/trunk/out/Debug folder:

AppRTCDemo-debug.apk

This is the main demo APK.

libjingle_peerconnection.jar

This is the JAR for libjingle.

libjingle_peerconnection_so.so

This is the ARM-based native library.

Running the APK on your device

To run the APK on your device, copy the file to a machine with ADB installed (and your device connected) and run the following command:

adb -d install AppRTCDemo-debug.apk

If all goes well, you should see a new application called “AppRTC”.  To test the application, launch a new browser on your desktop (not on the phone!) and navigate to http://apprtc.appspot.com.  Enable access to your camera and microphone and note the room number of the conference window.

Now, launch the AppRTC application on your device and enter the room number as part of the URL (ensure that there are no spaces).  If all goes well you should have an established connection with video and audio between the browser and the mobile device!

If you run into issues (and this is quite complex, so it’s usual) check ADB logcat for any errors and exceptions that are being produced by the AppRTC application.  Although functionally, this code is working, at the time of writing the TURN server being hosted on Google’s Compute Cloud is having some issues – so I had to dive into the code and configure the application to use an alternative – but that’s probably a good excuse for another post sometime in the future!

Either way, I hope this was useful and good luck!

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Designing a Web API for Mobile Apps

At Neudesic, almost every mobile project that we’ve been involved in has had some dependency on a Web API.  This has included APIs that we’ve had to create from scratch, as well as ones that already exist that the app has to consume.

As you can imagine, over the past few years, we’ve seen a fair share of good and bad API design.  In this blog post, I wanted to share some of my observations, thoughts, and questions that I ask of a well designed Web API, especially one that will be called from a mobile app.

1.  Are the basics being met?

First, the basics.  Without question, every Web API should be stateless.  There should be no session state, cookies, or server-side values used to hold any state of any kind.  Adding state adds complexity, and limits the ability for the API to scale, which for a mobile application that could reach millions of users is something that we want to avoid.

Also, endpoints of the API should be exposed through SSL by default.  SSL is easy to setup, performant, and should be enabled for any API that we either consume or create.  As you may have observed, using SSL as default seems to be a direction in which many other APIs are heading.

2.  How do we authenticate with the API?

Authentication is critical to a Web API, and (in my opinion) is one of the common pitfalls.  As a rule, user credentials should never be passed as part an API call.  Take the following example:

GET /accounts?username=simon&password=simon

Doing this is bad for three reasons:

Firstly, although the URL gets encapsulated as part of the HTTPS session, it is likely still visible in any logs on the Web server.  This often also applies to user credentials passed as HTTP headers.

Secondly, it makes debugging with users and other developers awkward (because you often need to ask for their username and password).  This is especially bad if the credentials are corporate accounts used for other systems.

Finally, and most importantly, these types of credentials typically have a long shelf life.  If the call is ever compromised, there’s a good chance that it can be replayed back to the service up until the password is changed, which could be many months (if ever at all).

To overcome this, some APIs use an application key or some other token derived from a HMAC algorithm.  This may work for some scenarios, but unfortunately if the key is exposed, it can be difficult to revoke.  This is especially true if the key has been embedded in a mobile app running on thousands of devices.

Fortunately, to overcome both of these issues, there is OAuth 2.0.  OAuth 2.0 works by having the user pass a set of credentials (typically a username and password) to an authentication service.  Assuming the credentials are valid, the user/application/consumer receives back an access token.  This access token is then passed as a HTTP Authorization Header to the Web API to verify the authenticity of the request.  Moreover, this access token has an expiry (I find an hour to be a good time frame) so that if someone were to get hold of the token, their usage of the API is limited to this timeframe.  (You can read up much more about OAuth 2.0 here)

There’s no doubt that implementing OAuth 2.0 involves more work, including setting up an authentication API and handing the lifetime of the token, but the end result is an API that is more secure and will also reflect the security model used by many others (e.g. Facebook, Google) – which means that you can even use these third parties as identity providers if you so choose.

3.  Is the API really using REST?

I’ve seen many examples of people thinking that they have a REST API when really they don’t.  Correct use of REST is about nouns, not verbs.  Let’s take this URL for example:

GET /GetAccountBalance?account_id=1234

Although the above URL is accessed over HTTP, it’s really not a REST API.

Using REST to it’s true intention means combining HTTP VERBS together with nouns or entities in the URL that represent the data you are exposing.  Instead of the previous URL, a correct REST syntax would be the following:

GET /accounts/1234

To create a new account we would use a HTTP PUT (together with a payload with the new account information)

PUT /accounts

To delete an account, we would use:

DELETE /accounts/1234

This noun-based approach can also work with hierarchical data.  For example:

GET /accounts/1234/transactions/50

Will return the a transaction (with id of 50) for Account 1234.

Overall, a good understanding of REST, together with a focus on exposing nouns instead of functional methods will go a long way to create a more more usable and accepted API.

4. How should we consume this API?

If you are dealing with an API that exposes a lot of entities, in addition to exposing generic REST endpoints, there are typically six things also worth considering:  Sorting, Searching, Filtering, Pagination, Helpers, and Partial Responses.

Sorting.  Should the API return a sorted list of data to the consumer/application?  If so, a sort parameter on the noun can be useful:

GET /accounts?sort=id

GET /accounts?sort=-id

As shown above, a leading hyphen to indicate ascending or descending sort order can be a great timesaver (and often negates another query string parameter for sort order).

Searching.  Similar to sorting, providing a way for consumers to search entities can be useful.  The use of the “q” parameter for search is somewhat standard:

GET /api/accounts?q=acme

Filtering.  Another useful pivot for any REST based API is the ability to filter on a particular noun.

GET /accounts?filter=balance%3E500

(You can choose to use the URL encoded character for > as shown above, or I’ve seen many other APIs use gt, lt query parameters).

Pagination.  A type of filtering, especially useful for large datasets.

GET /accounts?limit=50&offset=25

This above call will get the next 50 accounts, starting at the 25th entry.

Helpers.  With many APIs there are a number of common requests.  Maybe it’s the list of top ten customers, or the best sales people of the month. Putting these common requests as “helpers” into the API can be very useful for consumers, and can also help reduce the “chattiness” of the API by reducing the number of repeat requests.

GET /accounts/top-ten

Partial responses.  Finally, many consumers of the API (especially mobile applications) will want only a summary set of data.  This can be useful to build a list of items (in a master/detail view), without having to send the entire details for each item.

GET /accounts?fields=id,name,balance

Of course all of the above parameters can be combined as required.

GET /accounts?fields=id,name&sort=id&limit=100&offset=50

5.   What will the API return?

For the majority of APIs, especially those that will be consumed from a mobile application over a potentially slow connection, returning JSON is always good practice.  Compared to XML, data returned in JSON format will likely be more lightweight, and will require less parsing and processor overhead on the device.

With that said, there are cases where other formats might be required – for example, a legacy system that is already expecting data in XML.  In which case, you might want to consider allowing the consumer to specify what type of data to return either through the HTTP Accept header or through a URL action (useful if you anticipate doing a lot of debugging).

GET /accounts?format=xml

There has also been a lot of talk recently about HATEOAS (Hypermedia As The Engine Of Application State), a term coined by Roy Fielding.  While there are many articles and presentations that explain Roy’s initial intentions, for the purpose of this blog post (and my own sanity), HATEOAS in a Web API referring to the use of links that instruct the consumer where to go for related information.

For example, let’s imagine we made the following API call:

GET /accounts/1234

We might receive the following response:

{ "account_id" : "1234", "balance" : "100.90" }

With a “HATEOAS-compliant” Web API, we may also receive embedded links.  For example:

{ "account_id" : "1234", "balance" : "100.90", { "_links" : { "transactions" : { "href" : "/accounts/1234/transactions" } } } }

As you can see above, the API returns the data for the account, but also returns a link to the API call that will return all of the transactions for that account.  Think of these links as helping the consumer navigate to other related API calls.  (Incidentally there are a number of JSON formats for doing this, although I would recommend JSON HAL

6.  Are the methods of the API consistent? 

While it’s difficult to recommend what you should name your methods and other parts of your API, the key to success is often consistency.  For example, if you have the endpoints for your accounts here:

GET /accounts

For your invoices, it would be silly to have them here:

GET /order_entry/ledger/invoices_full

In an ideal world (and even one without HATEOAS!), a user should be able to guess what the API should be based on previous usage.  Keeping the paths and names consistent are key to making this happen.

Related to this, choosing the right case for APIs can be very important.  Having these two apis:

GET /accounts

GET /Invoices

will likely lead to issues because of the case mismatch on the entity name.  My recommendation is to use lowercase throughout (then there is no ambiguity) and to use snake case to conjoin words.  For example:

GET /customer_details

Spinal case (using hyphens) is also acceptable, but if you are doing a lot of descending sorting, you may want to be careful.

Finally, in terms of consistency, it’s always nice to be consistent with pluralization:

GET /accounts/1234/invoice

Assuming there are more than one invoice per account, this could also run people into trouble.  I would recommend deferring everything to plural to ensure consistency.

GET /accounts/1234/invoices

7.  How is the API versioned?

Versioning is important, especially if there are breaking changes in production environments.  There are a couple of ways to achieve this:

For large volume APIs where version consistency is critical, I would recommend placing the version information as part of the API call.

GET /v1.0.0/accounts

Versioning by using the URL makes it very explicit as to the version that the consumer is using.

For less critical systems, or for APIs where breaking changes are going to be rare, I would recommend that consumers pass an optional version number as part of the HTTP header.  If the version number is passed as part of the post, the consumer gets a specific versioned response, otherwise they’ll be receiving the latest version.

In addition to version numbers, I always like to see specific environments affiliated with the URL.  This is most easily done as part of the host subdomain, as it will likely correspond with the physical or virtual machine that the API is hosted from:

GET https://dev.example.org/accounts

GET https://uat.example.org/accounts

GET https://prod.example.org/accounts

The above makes it very clear whether I’m hitting the development, UAT, or production version of the APIs when I make my calls.

8.  How is the API documented?

If you have a well designed API, you do not need to spend hours of time documenting the API in a Word document.  If anything you are going to end up with a Word document that will become quickly out of date.  In terms of documentation, there are two things that I find invaluable:

Firstly, mandatory and optional methods and parameters should be documented.  It’s important that consumers understand what they can and cannot pass to the API.  What’s nice is that this documentation can typically be auto generated from the method signatures or comment blocks (which will keep your documentation in sync with your code).

Secondly, sample code to show how to call the API.  A few sample calls for each method can be a life saver and much more valuable than reams of documents.  In these samples, show how the request should be formatted and what the response looks like.

9.  What does the API return when things go wrong?

Returning useful error messages to consumers of your API is really important.  You should think about two types of error messages – ones that can be expressed with HTTP result codes, and ones that cannot.

For the ones that can be expressed through a result code, simply return the result code with an optional body of information (in JSON format).  For example, if the access token has expired, return a 401 HTTP error code, and maybe some JSON payload to help debugging.  Also, if any part of the system is down (e.g. the database connection can’t be established), I would recommend returning a 500 for clarity.  With any HTTP result code, remember to pass the right one.  A good rule of thumb is that result codes in the 400′s typically indicate an error with the client, whereas codes in the 500′s means that something has gone wrong on the server.

For errors that can’t be expressed through a HTTP result code, you should be returning a JSON payload that contains a minimum of two pieces of data – a unique error code for the issue, and a message aimed for the consumer/developer of the application to help them debug.  For example, if the consumer tried to create a new account without including all of the mandatory fields, this would be a useful error to return:

{ "error" : 16, "debug" : "The mandatory field for balance was missing in the request" }

Some recommend returning a user message also, which can be useful.  Others use the error code to create their own message to pass to the user.

10.  Finally, what else should we be thinking about for using the API in production?

There are many considerations for using APIs in production – here are just a few:

How are you going to make money from your API?  Are you thinking about a transaction cost per call, freemium, capped model, or something else?  Many of these systems are going to require some kind of API metering – which isn’t necessarily hard, but is definitely something else to consider.

Are you going to rate limit your API?  How are you going to prevent a rogue customer, application, or process, who wishes to call your API hundreds of thousands of times?  Fortunately, there are answers to this – including RFC6585 which specifically deals with rate limiting – but again, something that you should be considering.

Should your API provide cached results? Is this something that can improve the performance for your consumers, and also prevent unnecessary calls to back end databases and other systems?

How is your API going to work over a low bandwidth connection?  Your API might work great on your FIOS line here in the US, but do consumers get the same experience when calling the API from a J2ME application from a cell phone in the middle of Africa?  There are many ways to simulate throttled connections and this should be something that is definitely worth testing for.

Finally, and arguably most importantly, how can you get everything to go through your API?  Instead of thinking of an API as a companion to your existing Web-based applications, what would it take to push everything through this API – treating the API as a single source of truth?  It might sound scary, and undoubtedly it’s additional work to have everything using the API – but a single API that every application uses has the potential to offer a lot of re-use and sharing as you develop your API over time.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

jQuery Mobile and AngularJS Working Together

Both jQuery Mobile (jQM) and AngularJS are awesome at what they do, but getting them to play nicely together can be tricky.  As you may have discovered, both want to manipulate the URL/routes and DOM such that it’s very easily to get them in conflict.  Having been through this recently, I wanted to share some recommendations to get them working together:

Load jQM libs before AngularJS

Because both frameworks heavily manipulate the DOM, it’s important to get the load order right.  I found that loading AngularJS first led to some interesting (and annoying!) UI functionality.  The correct order should be jQuery first, followed by jQM, and then AngularJS:

<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular-resource.min.js"></script>

Let jQM handle the URL routing

I’m likely to get flamed for this by MV* purists, but I recommend letting jQM handle all of the URL routing – and not using AngularJS for any routing.  Firstly, I spent a lot of time trying it the other way (disabling routing for jQM, and configuring various routes, templates, partial files, etc.).  Even when it did work, it was just a mess – it looked like someone had taken a shotgun to my jQM app and blown it into several pieces.  Secondly, I would argue that URL routing really shouldn’t be a primary consideration for a mobile Web app.  The app is more likely launched by an icon on the home screen vs. a search or link with any type of query string.  Even if it does, a simple check for a null scope is all that’s required.

Create a single Angular controller for a group of jQM pages

Conforming to #2 means that you can create a single controller that spans a number of individual jQM pages.  This usage results in very elegant single HTML page together with a single controller – yet has the advantage of offering multiple pages to the user.

To demonstrate this in more detail, and because you can’t have enough Todo list apps, I’ve put together a sample using jQM, AngularJS, speaking to a service using Node, Mongoose, and MongoDB.  (To run, you’ll need a local Mongo DB called “todo” with a collection called “tasks”).  It definitely shows the power of both frameworks running together.  In just 75 lines of HTML and 29 lines of JavaScript for the controller, I have a mobile app with full CRUD support.  Hope you find it useful.

NewImageNewImage

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

On-Demand VPN using OpenVPN for iOS

Many large organizations have existing VPNs in place, and the rise in development of enterprise mobile applications often requires that apps running outside the firewall need to “VPN in” before they are allowed to access any corporate resources.

While enabling a VPN is fairly easy on most mobile devices, I’ve found that many IT organizations would like to automate this such that the device automatically connects to the VPN when the Enterprise App or an internal Website is launched. Having gone through this with a couple of customers, I’ve put this post together to highlight how this can be done.

Which VPN types support On Demand for iOS?

iOS 4.2 introduced features designed for the enterprise. These features included several VPN clients (L2TP, PPTP, Cisco IPSEC), many of which can be configured to automatically initiate the connection based upon DNS requests for certain domains.

While this on demand feature has been around for a while, it does have a couple of caveats. Firstly, it’s only available for SSL based VPNs. An SSL-based VPN is a connection that relies on a client/server side certificate for authentication. Having an SSL-based VPN means that the connection can be established without asking the user for credentials (e.g. a password or RSA token). Because an on-demand VPN could be connecting and disconnecting every few minutes, this makes sense as prompting the user could cause a jarring user experience. Secondly, the on demand VPN can only be setup using the iPhone Configuration utility. While you can create a VPN connection on iOS devices (under general/settings), it’s not possible to create an SSL-based VPN or specify any of the on demand domains.

With this in mind, I’ll be showing how to establish an On Demand VPN using OpenVPN and the OpenVPN client for iOS that was released earlier this year.

Server-Side Setup

The first step is of course to setup an OpenVPN server. If you don’t have access to one already, there are plenty of guides to help you set one up. If you don’t have access to a spare machine on the network, you can also use a Linux VM instance hosted on EC2, Azure, or any other hosting provider. This article is a pretty good guide for setting this up on EC2 and the instructions should be able to be tailored to other hosting environments.

Generating Certficates and Keys

Once you have your OpenVPN server running, you’ll need to either import or generate certificates and keys required to establish the connection. If you don’t have access to certificates already, you can find some great documentation here on how to create your own using the EasyRSA project on Github. (Scroll down and look for instructions on using easy-rsa)

These are the certificates you’ll need to generate using EasyRSA:

ca.crt (CA certificate required for both server and client)
dh2048pem (A 2048bit Diffie Hellman key that is required on the server)
server.crt (The server-side certificate)
server.key (The key for the server-side certificate)
client1.crt (The client-side certificate)
client1.key (The key for the client-side certificate)

Configuring OpenVPN 

Place the certificates in a folder called keys (under /etc/openvpn/keys) and modify your /etc/openvpn.conf file to look similar to the following:

tls-server
port 443
proto tcp-server
dev tun
ifconfig 192.168.2.1 192.168.2.2
keepalive 10 120
comp-lzo
persist-key
persist-tun
verb 3
push "ifconfig 192.168.2.2 192.168.2.1"
push "redirect-gateway"
dh keys/dh2048.pem
ca keys/ca.crt
cert keys/server.crt
key keys/server.key

This should be fairly straightforward to understand from the documentation, especially if you’ve used OpenVPN before. As you can see, we are creating a peer to peer connection using two private IP addresses (192.168.2.1 and 192.168.2.2). Don’t worry if these don’t match your internal network on the OpenVPN box – they don’t need to in order to get this up and running.

For the purposes of this article, I have the VPN running on a tcp:443 connect, but feel free to adjust the protocol and port to match your own environment (assuming that you have the necessary ports open on your Firewall).

Once you have the server configured, you can start OpenVPN:

openvpn --config /etc/openvpn/openvpn.conf

Assuming that the server starts OK, you can move to the next step.

Installing and Configuring the Client

The OpenVPN client can be found on the AppStore. At the time of writing it’s version 1.0 build 47, which has a few bugs here and here, but still seems to work well.

After you have this installed, go ahead and install the iPhone Configuration Utility on your Mac. This can be found on the Enterprise iPhone Support page (http://apple.com/support/iphone/enterprise). Don’t worry – although it’s called the iPhone Configuration Utility, this will also work for setting up a VPN on an iPad device also.

After launching the utility, create a new configuration profile. In the general tab, enter the mandatory fields for name and identifier. Then, click on the credentials tab. We need to import the client certificate and key that was generated earlier using EasyRSA.

Unfortunately, the iPhone Configuration Utility (which we’ll call IPCU from now on) doesn’t support importing .CRT and .KEY files directly, so we’ll need to generate a PKCS#12 file for use here. To do this, in the Terminal locate your client certificate and key files, and run the following command:

openssl pkcs12 -export -in client1.crt -inkey client1.key -out client1.p12

The result of this should be a .p12 file, that you can now import into the credentials section of IPCU.

Note:  When you generate the .p12 file, you will be asked for an export password for the file. Enter something, and use the same password in IPCU (there is a field just under the certificate picture). If you don’t enter a password, you will likely get a profile error when you try to deploy this to the device.

With this done, now navigate to the VPN tab and create a new VPN connection. IPCU doesn’t support including an OpenVPN config file, so we’ll have to create the majority of the settings in this tab – this is where things get fun :-)

Give the connection a name, and select “Custom SSL” for the connection type. For the identifier, use the following:

net.openvpn.OpenVPN-Connect.vpnplugin

This is telling the VPN client that a specific bundle ID (the OpenVPN app) should be used for this connection.

Next, in the Server field, enter the DNS name or IP address for your OpenVPN server.

The Custom Data contains keys and strings that replicate what would have normally gone into a config.ovpn file. These are the entries that you will need:

ca – This is a tricky one to get right. We can’t point it to a ca.crt file, because there is no way of bundling a file using the IPCU tool. To overcome this, open the ca.crt file in TextEdit and replace all of the newline/carriage returns with \n. What you should end up with is a single (long) line of text that starts with —–BEGIN CERTIFICATE—– and has several lines delimitered by \n ending with —–END CERTIFICATE—–. Once you have this, paste this entire line into the value for the ca key.

comp-lzo - enter the key, but you don’t have to give it a value.

dev – set this to tun

port – set to 443

proto – set to tcp

(Again if you are using something other than TCP port 443, feel free to change)

remote – set to [your server name] 443

(replace your server name with the DNS name or IP address of your OpenVPN server)

verb – set to 3

Here’s a quick screenshot of my profile:

NewImage

That should wrap up the custom data piece.

Under User Authentication, select Certificate – and then under Credential select the client certificate from the drop down.

Finally, check the “Enable VPN On Demand” box, and in the below table enter the domain names or IP addresses for the hosts that VPN is required for. For this tutorial, I have a single entry for 192.168.2.1 with “Always Establish”.

That’s it!

This configuration should be enough to get VPN On Demand working with OpenVPN on the iOS client. To test, deploy the configuration profile to the device. Assuming that this works, open a browser and browse to 192.168.2.1 – this should invoke the VPN connection and forward the requests to the OpenVPN server. If you have a test page running on the OpenVPN server then this should be displayed in the browser.

If it didn’t work…

There’s a good chance that things won’t work first time, just due the complexity of the setup.  Here are some of the common tips/tricks that I found during the process.

- Firstly, the console window in IPCU will be your best friend. The most common error I saw was related to the CA certificate. If you get these, it likely means that your CA entry in IPCU is wrong. Go back and make sure you’ve correctly replaced the linebreaks with \n’s and retest.

- There are a few “bugettes” in the iOS client. As of build 47 these include:

The tcp-client param is not supported in the iOS client. Use tcp instead.

The client expects ifconfig information to be pushed to it (using the push lines in the server config). It doesn’t seem to be possible to configure ifconfig lines locally.

The “redirect-gateway” seems to be required for the iOS client – whereas Tunnelblick connects without it.

- Workflow. Getting VPN On Demand working right off the bat can be hard, especially if multiple parts of the configuration are wrong. If you are new to OpenVPN, you might want to setup a VPN with a the following configurations (in terms of complexity just to get working):

OpenVPN w/ Secret Key – using Desktop machine (use Tunnelblick for the Mac)
OpenVPN w/ Certificate – using Desktop machine
OpenVPN for iOS w/ Certificate – using the actual OpenVPN for iOS Client (not IPCU)
OpenVPN for iOS w/ Certificate – using IPCU 

- Browser Refresh.  If it looks like everything is working (VPN established, etc.) but you still don’t get your Web page, try refreshing the browser/making a 2nd request.  I’m not sure whether this is something in the config, or a “feature” of the OpenVPN client for iOS – but I’ve found that refreshing often helps brings the page to life after the VPN connection has been established.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

QCamera

Doing mobile development on a Mac? Need to show your mobile device using your USB camera during a presentation?

Here’s a quick utility that I hacked together over the weekend to do just that. Supports mirroring/reversed images (which is why PhotoBooth won’t work for this) and borderless mode to keep it in the foreground over an IDE or presentation. Hope you find it useful!

Available on the App Store Badge US UK 135x40

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Uploading Photos from Mobile Web Applications

Here at Neudesic, we’re fortunate to be involved in many exciting HTML5/Mobile Web applications for different organizations. For many of these projects, one of the common requests, especially for field-facing mobile applications, is the ability to upload a photo from within a web page in a mobile browser.

If you are not familiar with the space, you may think this should be default behaviour, but surprisingly uploading media is one of those areas that is still going through the standardization process. Eric Bidelman has a great overview of the three “rounds” of standardization that have taken place so far as part of the Device API working group.

What can you do today?

While Eric’s article gives a great overview of what’s likely to come, the purpose of this post is to explore what’s possible today, outlining the relative pros and cons of each approach.

Firstly, let’s take a look at what’s supported out of the box:

Android

If you are using Android 3.x+ (i.e. either Android tablets running Honeycomb or later, and Android phones running ICS) – or users are running Chrome or Firefox Mobile for Android, the browser will support an input element that can invoke the camera:

<input type="file" accept="image/*" capture="camera">

Simply add this element to your web page, and together with some server-side processing for the upload, users can upload the image from their device.

Android Image Upload

As Eric mentions in his article, it does look like things are heading towards getUserMedia() instead. Although this new API works with latest versions of the desktop version of Chrome, we haven’t found anything that works on mobile browsers as of yet.

iPhone/iPad

Unfortunately, the input element above does not work on Mobile Safari on iOS5 today – the experience for the user is just a disabled button. This is true for the recently released version of Chrome for iOS also (as it’s just a wrapper over UIWebView).

Things are changing however.  At WWDC this year, Apple publicly announced support for photo and video uploads within Mobile Safari shipping with iOS 6. It’s difficult to say much more about the implementation here (as the developer/beta programs are under NDA), but if you have access to Apple’s developer program, it’s definitely worth checking out.

Apache Cordova (PhoneGap)

If you want to support earlier Android versions, and/or can’t wait for iOS 6, arguably the most popular choice is Apache Cordova (previously known as PhoneGap). Apache Cordova provides a native wrapper around HTML-based content, and supports several platforms today – including iOS and Android. The Cordova API supports media capture, and with a couple of lines of JavaScript, it’s possible to instantiate the camera or invoke the camera rolls within your Mobile Web application.

Camera Roll on iOS

Pros: Works with the most popular versions of mobile browsers, and as of now, Cordova provides a good user experience for the user. The user presses a “add photo” button in the HTML application, and the native wrapper invokes the camera control without the user needing to know whats going on. If using the camera roll, the API also supports the option of uploading multiple photos.

Cons: Using Cordova does however change the deployment model for the application. No longer can you just visit a Web site to use your application – you now need to think about distributing your application – either via the AppStore for public-facing applications or through another channel for enterprise apps.

In addition to the deployment, Cordova also introduces several options that need to be considered for actually transfering the image to the site. The default is to use Base64 encoding, which is good for small images, but we’ve experienced performance problems on large images from 5MP+ cameras. The Cordova API does support a File Transfer API, which works well except it doesn’t yet support authentication, so you’ll need to create an anonymous area to post your photos to. If you do need authentication, you’ll want to send the photo directly after capture, which will likely mean writing a custom Cordova plug in and using NSUrlConnection to send your photo to the server.

Companion Application

An alternative approach to wrapping your HTML content with native code is to ship a “companion application” responsible for uploading the photo.

Both iOS and Android support custom URL schemes, which means that applications can respond to different URL requests from the browser. For example, I can create a native application responsible for taking and uploading pictures, using a custom URL scheme called simonphoto:// which I can then pass various parameters – for example, the ID of a project that I’m uploading photos for. Once the user clicks on the simonphoto:// link within the mobile browser, the application launches and I can take and upload as many photos as I want.

Pros: The biggest draw to this approach is that the HTML application doesn’t need to be wrapped with any native code.

Cons: While I don’t have to wrap my HTML, the user still needs to obtain the companion application, which will likely involve a trip to the AppStore or other link for download. In addition, even when the companion application is downloaded, the user experience isn’t quite as slick as the the PhoneGap approach. For example, in iOS there is no natural way of getting back to the Web app once the native application is ready to hand back control (unless you pass a return or app id in the parameters). Also, there is no way of checking whether the companion application is installed or not from the Web page.

Picup

Picup is an example of a free companion app that works in a similar way as outlined above. It uses the fileupload:// URL scheme to invoke the Picup app, which much be installed.

Picup Application

Pros: As above.

Cons: As above. No version for Android (although I’m sure there are equivalent apps available).

Email

Finally, a very simple approach, but one that I’ve seen a couple of people use is sending the photo via email. Your application has a “mailto” link which includes a subject (maybe the ID corresponding to the application) and body that reads “Please remember to attach your photo”. The user attaches the photo manually and it’s sent to a server-monitored email store for processing.

Pros: Nothing native here, and deployment model stays the same.

Cons: Funky experience for the user. You’ll also need to setup a server side environment to handle the incoming emails, strip the attachments, and correlate with your application.

Summary

A lengthy post, but hopefully it gives you an overview of how to do photo upload from mobile devices today. To summarize:

If you are writing an application that won’t be released for a few months, and will primarily target Android ICS and iOS6, you should be able to use the <input/> element outlined above to invoke the camera and upload a picture. If you do this, make sure you understand the transition to getUserMedia as the specifications mature.

If you are writing an application that needs to target today’s platforms – namely Android 2.x and iOS5, you’ll either need to use Cordova to create a wrapper or a companion application (either hand crafted, or something like Picup). Choosing between Cordova and a companion application is a balance of user experience vs. deployment. A Cordova application will keep the user experience seamless, but you will be responsible for the deployment of the application as a result.

If you don’t want to do any device development, and are just looking to provide a shortcut for users to send photos, you could consider the basic mailto: / email link approach.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Upgrading your Windows Phone 7 to Mango RC

In late July, Microsoft announced availability of a new build of Mango, build 7712 – also commonly known as the RC Build.  Given that we are close to RTM, yet it may still take carriers some time before deploying Mango to your device, you might be itching to try out the new bits.  If you are, but don’t know where to start, I’ve put together this quick guide based on my own experience of updating my phone, an AT&T Samsung Focus.  Note: As you would expect, if you do decide to upgrade your phone, this is entirely at your own risk.

Before you begin, you’ll need a few things:

1.  A Windows Phone 7 device with all of the current updates (a.k.a. NoDo) installed.  Double check the updates in the Zune application to make sure everything is up to date.  You should see that your WP7 build number is 7390.

2.  Zune Software 4.7.1404.  Although 4.8 was released yesterday, you won’t be able to do the update with this version (yet).  Download 4.7.1404 from here if needed.

3.  Windows Phone 7 Support Tools.  You can download this from here (32bit, 64bit).  Run the installer, but you don’t need to run the application.

4.  Enough battery power to get you through several updates (when the phone is updating, your device isn’t being charged).  I would avoid trying this with anything less than 50% charge.

5.  The mango update tools.  If you are a registered Windows Phone 7 developer, you can supposedly download these from the Microsoft Connect site.  If you are not (or like me you are, but couldn’t find the tools on Connect), you can find a version of the tools on this site.  (Note:  Follow Step 1, and yes, you have to wait for 45 seconds for the download link to work).

With all of the above in place, run the Update.bat from the Mango update tool download.  Assuming there are no errors, you should see something similar to the following.

image

Firstly, the tool will make a backup of your device to the c:\PreMangoState2 directory, and install the updates necessary for your device to receive the pre-release Mango bits.  The time this will take may vary, but on my machine it took 112 seconds to backup, and 70 seconds to update the device.

Once the batch file completes, and the device reboots, the Zune software should automatically launch.  You’ll be shown that an update is available (likely build 7403).

image

Choose to install this, which will then download the Zune 4.8 software.  After the Zune software has been updated, the phone will be updated to 7403, which should be a fairly quick update.

As the phone reboots once more, the Zune software will do another check – and this time will pick up the 7712 build, which is Mango RC.  Choose to download and install this one.  This is where the battery power is important, as this install can take quite a bit of time to complete (let’s just say that I’ve been able to pen this blog post, and it’s still not 75% of the way there!).

Be patient though – one final reboot, and you’ll be running the latest Mango RC (Build 7712) bits!  Enjoy!

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Running Visual Studio 2010 on the Mac

Following a few recent presentations, I’ve had a couple of people ask how I run Visual Studio on the Mac.

You’ll be sad to hear that I don’t have a special version of Visual Studio for Mac OSX – instead I am using VMWare Fusion 3.1 to run a copy of Windows 7 in a virtual machine. Fusion has a mode called “Unity” which allows windows from the virtual machine to interact with windows on the host operating system (even to the point where I can put icons for Windows-based applications in the dock on the Mac). There is a little performance hit running applications in this way vs. a full screen virtual machine, but it’s certainly useful for presentations where you are flipping between both environments.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS