Open Source Spotlight: ngForge

header

Heya TriggerFolk!

This week we’re going to be taking a look at a great Open Source project started by Trigger.io user Andres Olave:

ngForge provides a set of idiomatic AngularJS wrappers for the
Forge modules that allow for easy & clean integration with Google’s AngularJS framework.

Here, in his own words, is Andres to tell you all about it…

An Introduction to ngForge

Angular & Trigger.IO are a great combination for developing mobile apps. Using either iOS or Crosswalk for Android it’s possible to build hybrid mobile apps we could only dream of in the past few years.

ngForge is a set of Angular wrappers for Trigger.io Forge modules with the aim to:

  1. Seemlessly switch between mobile & browser implementations
  2. Provide a AngularJS friendly experience:
    • Dependency Injection not globals.
    • Promises not callbacks.
    • $http API equivalency for the request module.
  3. Provide a basis for use in modern JS development:
    • Use the browser as the primary development environment – because there are many commonplace, well supported, free tools.
    • Don’t require trigger.io builds in the browser environment.
    • Be optimised for standard JS build tools: Grunt, Gulp, etc.
  4. Allow services to be configured & reconfigured on the fly in browser mode.

How it works

Using AngularJS emphasises the use of dependency injection. The typical use is to inject services into controllers, or the Angular’s $http service into services.

Let’s say you are building a web app with a service that has a saveLocally method:

With ngForge you can now instead use $forgePrefs which delegates to the forge.prefs module when running as a mobile app, and to localStorage when running in a browser.

For example, we can inject it into any service implemented in Angular:

This way AngularJS allows us to implement the service before it provides the $forgePrefs service and ngForge can detect whether it is running in a mobile environment or a browser.

  • if it’s a mobile environment ngForge delegates all service calls to the Trigger.io module.
  • if it’s a browser environment ngForge:
    • returns mock data – for example $forgeContacts returns mock data.
    • and/or implements a mock version of the module – for example $forgePrefs delegates to localStorage in browser mode.

In fact even if ngForge doesn’t mock out a method, it is still able to delegate service calls to Trigger.io in mobile environment mode.

Promises NOT callbacks

The Forge module API’s are currently still based on Node.js-style callbacks which often lead to callback hell and are not a natural fit with Angular’s Promises-based approach to deferred and asynchronous computation.

ngForge extends the Forge Module API’s with support for Promises which allows you to use them in the same way as you would in your regular Angular app.

For example, using standard Trigger.io you’d access forge.prefs like this:

With Promises, it instead becomes:

Much cleaner wouldn’t you agree?

Service Configuration

In browser mode, ngForge services can be configured by using Angular config methods. You may want to configure:

  1. Mock data: for example the mock contact book data used by $forgeContact, or
  2. Implementation configuration, for example what key to store data under when using the localStorage version of $forgePrefs.

Each service documents what is configurable. Here is an example config:

Using $forgeHttp instead of the forge.request module

Trigger.io’s forge.request module offers cross-origin access and native performance for HTTP request.

However, the request module’s API is based on a subset of the JQuery API and if you are using Angular it would be preferable to replicate the $http service API. (See the Angular $http service documentation for more details.)

This is what the $forgeHttp API looks like:

The following methods are not implemented as yet:

Additionally, the config object supports the following properties:

  • params{string|Object}: Params that are not already query strings are serialized as query strings and appended to the URL.
  • data{Object}: Data to be sent as the request message data. If it’s a get request then it is serialized as a query string and appended to the URL.
  • headers{Object}: Map of strings representing HTTP headers to send to the server.
  • cache{boolean|Object}: A boolean value or object created with $cacheFactory to enable or disable caching of the HTTP response.
  • timeout{number}: timeout in milliseconds
  • responseType{string}: See XMLHttpRequest.responseType.

All these methods return a promise that support the standard methods: then, catch & finally methods that take function with a single argument of the http response object. It also supports the deprecated success & error methods for handling responses. See the Angular Promises Documentation for more detail.

Results of GET are, by default, not cached. Caching is supported in the same way as in $http, that is, by default using simply the value true, or by an instance of $cacheFactory. (See the Angular $http caching documentation for more information)

We also support interceptors that allows you to implement cross cutting concerns for requests or response. Simply add interceptors to the $httpProvider as in the Angular documentation.

The future

AngularJS is a 3rd generation web framework but is already being replaced by 4th generation frameworks such as Angular2 & ReactJS. These feature simpler programming models, ECMAScript 2015 (or even TypeScript) & vastly superior performance.

There are some exciting Trigger.io updates coming that will make it possible for us to update ngForge with support for Angular 2 and Observables and we are planning broad framework support for ngForge in the near future.

I hope you enjoyed reading this quick introduction to ngForge.

Check the project out on GitHub and if you have any questions please feel free to drop me an email: andres@sportwize.me

Fork me on GitHub

Big up to 7cups.com

7cups banner

Trigger.io users are people we are proud to be associated with! The recent growth of 7cups.com is a testament to the kind of skill and effort we regularly encounter amongst the Trigger.io community.

The aim of the 7cups initiative is to provide online emotional support in a world with “an immense love deficit”. From their website:

7 Cups of Tea is an on-demand emotional health and well-being service. Our bridging technology anonymously & securely connects real people to real listeners in one-on-one chat.

Anyone who wants to talk about whatever is on their mind can quickly reach out to a trained, compassionate listener through our network. We have hundreds of listeners who come from all walks of life and have diverse experiences.

Glen Moriarty, Founder and CEO, is a psychologist who is passionate about the Internet’s power to help people lead better lives. He is joined by a team of professionals with a wide range of capabilities, from counselling and social work to engineering and web design.

As well as a running a succesful website and an app which is available on both IOS and Android, 7cups also maintains an active reddit community, and encourages academic research interest through their Open Research Platform

Working with Trigger.io

header

We asked Ezra Morse, the Full Stack Engineer at 7 Cups, to tell us a little about working with Trigger.io as a platform for development.

Q – Why did 7cups choose to work with Trigger.io?

As the world’s largest emotional support network, 7 Cups is about bringing people together. The last thing we need is to sacrifice dev time on hunting for platform bugs, solving plug-in conflicts and triaging build issues.

Trigger.io allowed us to swiftly convert a legacy, first-generation mobile website into a reactive one-page application with the native plug-ins we needed, while keeping our focus where it should be: on user experience and our community.

In the end, we were able to produce a lean, performant app that isn’t mired by stability issues or the long iterative cycles characteristic of a fully native app. We finally have a stable and evolving application that better positions us to reach more people in need.

Q – What is your overall experience of hybrid development in today’s market?

To be honest, Trigger.io wasn’t our first choice on this project. Let’s just say that our first pass at modernizing our app could be described as wanting to have our cake and eat it too.

We bought into too many promises and tried to relegate far too much functionality (UX included) to the native device, thereby leaving us with a slow, bloated hybrid-application that would crash as often as freeze. So we went from an extremely bad scenario where our concerns about speed and the memory footprint of the app simply didn’t allow us to take any chances.

If we wanted to keep our app hybrid, a cordova-flavor just wasn’t going to give us the lean and stable app we wanted to share with the world; we simply could not afford to have performance issues continue to stand in between the people on each end of the device.

In summary, I feel a lot of the hybrid approaches fail to keep it simple on both the application level and the build process, and thereby, the end product suffers. As hybrid developers, should we really need to focus on too much more than what is going on inside that single webview?

7cups screenshot

Thanks Ezra, for making the time to speak to us and fill us in on your development process. We look forward to many more collaborations in the coming months.

From everyone at Trigger.io, keep up the good work!

Discover Trigger.io Forge v2.4: Runtime App Permissions

runtime-app-permissions

Following our announcement of Trigger.io Forge Platform v2.4 earlier this month I’m pleased to present, as promised, our first article about the new features that landed with this release.

Today I’ll be covering the support we’ve added for managing iOS and Android runtime permissions and showing you:

  • How you can use our Runtime Permission features to increase your app install rates.
  • How to dynamically adapt your app to the permission preferences of your users.
  • How to save your users from an epic journey into their device preferences if they didn’t grant an app permission the first time round.

What Are Runtime Permissions?

Both iOS and Android apps execute inside a sandboxed environment which places hard restrictions on the device resources accessible by your app.

The goal of this sandboxed environment is to limit the amount of mischief a malicious or misbehaving app can inflict on your device.

In a perfectly secure world, apps would not be able to access any resource outside of their own environment. Unfortunately this would also mean we could not develop apps that make use of device features such as cameras, photo albums, geolocation or notifications.

The compromise then is for apps to explicitly request the user to grant specific “device permissions” to the app.

This informs your users of the device capabilities they are entrusting to your app, but it also places the onus on you, the app developer, to give the user a reason to trust you!

On older versions of Android, and a lesser extent iOS, the user was forced into an all-or-nothing decision about whether to grant access to resources during the initial app installation process.

Given how long the list of requested device permissions can get this unfortunately results in many users responding to such a big “ask” by simply not installing the app.

It’s a little hard to win your user’s trust if they’re not running your app in the first place, right? :-)

Luckily, with the release of Android Marshmallow, Forge v2.4 and our new forge.permissions module, users no longer have to make an upfront leap of faith as it’s now possible to incrementally request device permissions at runtime on both iOS and Android.

This helps your users feel more in control, while simultaneously giving you a chance to make a powerful case for the benefits of trusting you with their device.

Forge and Runtime Permissions

Up till now, the way we’ve dealt with runtime permission requests on iOS and Android Marshmallow has been to automatically trigger the system permission request dialog whenever a module calls a native API requiring that permission.

For example:

Which results in an app flow that looks like this:

Default Runtime Permissions Flow

The good news is that this behaviour has not changed with the release of v2.4 and if you’re satisfied with the way your app works you can stop reading right now. :-)

However, an important gotcha to be aware of is that both Android and iOS devices have the following behaviours hardcoded into their operating systems:

  • On Android: When a user clicks “No” the first time they are asked, they will have the option to prevent the app from making subsequent requests.
  • On iOS: When a user clicks “No” the first time they are asked, the app will be prevented from making subsequent requests.

What this means is that once a permission request has been denied, there is a high likelihood that the only way the user can grant that permission in future is by digging in their device’s System Preferences.

Or to put it another way, once a permission request has been denied (iOS) or disabled (Android) all future requests to forge.contact.selectAll() will only ever trigger the error callback.

Not an ideal situation, but all is not lost!

We created the forge.permissions module to address precisely this problem and to help you get more control over when and how permission requests are presented.

How To Use The forge.permissions Module

Step 0: Update your platform version and modules to the latest versions

To use the forge.permissions module you need to be on at least platform version v2.4.1 and at least the following module versions:

module version
contact 2.9
calendar 2.7
geolocation 2.4
camera 2.3
file 2.11

Step 1: Add the permissions module to your app

In the modules section of your app’s src/config.json file add the module as follows:

Alternatively, launch the Trigger.io Toolkit and navigate to the Modules section of your app and search for the permissions module.

Step 2: Check Whether You Need To Make A Permission Request

Before we actually request a permission we first need to check whether the user has already granted the permission or not.

Once we know this, we will know whether we will need to initiate a permissions request or whether we can proceed normally with our app.

The API that will give us this information is: forge.permissions.check()

So, let’s say we have a feature that needs to use the forge.contact.selectAll() API which relies on the forge.permissions.contacts.read permission.

To perform the check you then simply do something like this:

You can find a list of modules and the permissions they require by checking out the Permissions Module Documentation

When granted is true you can simply continue with your app flow and when it is false you can take the steps needed to make a permission request of the user.

Step 3: Request Permission

Now that you know how to check for a permission, you will need to know how to handle the case where the permission has not yet been granted.

To do this we’ll use the forge.permissions.request() API:

Note that, although the user will be presented with the permissions popup when you call forge.permissions.request() this is slightly deceptive.

The dialog the user will see is not generated by the device operating system but rather by the module. If the user clicks “No” in this dialog any future requests for the permission will no longer fail automatically.

It is only after the user has clicked “Yes” that the real system dialog is presented.

With this code, your user will be asked for permission when you call forge.permissions.request() and you then have the option to take an alternate action if the user did not grant the request.

All Together Now

Now that you know how to check for and request permissions, let’s look at an example of how you could put all the pieces together for a smooth user experience in your app:

Custom Runtime Permissions Flow

There are a couple of advantages to doing it this way:

  • The call to forge.permissions.check() provides a logical place to fork your app logic depending on whether the user has already granted the permission or not.
  • By linking the forge.permissions.request() call to a user action which explicitly relates to the permission being requested you greatly reduce uncertainty in the user’s mind about the purpose of the permission request.
  • Being able to check the outcome of the permission request you’re able to easily update your application and explain to the user why you need access to that permission.

That said, this is only one example of how to do it and you may find your application needs a different approach.

For some great ideas on increasing Runtime Permissions conversion I highly recommend you check out this article by Brenden Mulligan: The Right Way To Ask Users For iOS Permissions

Finally, don’t forget to check out the documentation for the Permissions module!

Conclusion

I hope you enjoyed this quick journey through the iOS & Android Runtime Permissions models, how Forge handles permissions by default and the tutorial on how to use the forge.permissions module to implement custom handling of runtime permissions.

As always, please hit us up at support@trigger.io if you have any questions or comments!

Trigger.io Forge v2.4.1 – Intel Crosswalk, Runtime App Permissions & Android Studio support

crosswalk-project-logo

Towards the end of last year I wrote about our upcoming 2.4 release and today I’m happy to announce its arrival!

We’ll be covering the individual features landing with v2.4.1 in more detail over the coming weeks but let’s take a quick look at the highlights:

New forge build target: Crosswalk

crosswalk-project-logo

With the release of Trigger.io Forge v2.4.1 our crosswalk target has finally graduated from the beta branch and has been declared ready for production use.

Anyone developing hybrid apps for Android will be familiar with the myriad of compatibility issues that pop up when you start testing your app against different versions of Android.

Android versions before v4.4 shipped with a proprietary System WebView which lacked many basic HTML5 features, performed poorly and suffered from compatibility issues.

Android versions after v4.4 use whichever version of the Chrome-based System WebView was current when the device shipped.

The very latest versions of Android now periodically update the System WebView when newer versions of Chrome are released but this creates new problems when System WebView changes suddenly render your code inoperable.

The Crosswalk Project resolves these fragmentation issues by integrating the open-source Chromium WebView with your app.

By using our crosswalk target you can now use the latest web standards across all Android devices and control when you want to upgrade your app to support newer Chromium releases.

For more background information please read: Solving Android Fragmentation with Trigger.IO Forge and Intel’s Crosswalk

Runtime App Permissions

runtime-app-permissions

With the release of Trigger.io Forge v2.4.1 and our new forge.permissions module we fully support the new Android Runtime Permissions framework and give you complete control over when and how your app makes native permission requests.

By default, all forge module API’s will now only make a request to the user for permissions when the API is called and not during application startup.

While this has the benefit of not requiring a user to make an “all-or-nothing” decision when they install the app it still has the downside that it can quickly get quite complex to handle situations where users deny permission requests.

By using the forge.permissions module you have fine-grained control over permission management, can easily handle cases where permissions are denied and greatly increase the probability that users will grant your app the permissions it requires.

Android Studio Support

android-studio-logo

With the release of Trigger.io Forge v2.4.1 we have migrated our cloud compilation service to the Gradle build system and updated our Forge Native Module SDK to support the Android Studio IDE.

While we’re huge fans of the IntelliJ IDEA-based Android Studio the primary motivator for this shift came about because Google have now officially deprecated Eclipse for Android development.

This means that all development and official support for the Android Developer Tools (ADT) in Eclipse have now ended. Specifically, this includes the ADT plugin as well as the Android ant build system.

We’ll continue to support native module development with ant and Eclipse for as long as practical but you may be pleasantly surprised at how much easier Native Module development can be with Gradle & Android Studio!

Upgrade your app to Trigger.io Forge v2.4.1

You can find more information in the v2.4.1 release notes but the following steps should get you going:

Step 1 – Upgrade your platform version

Open your app’s src/config.json file in your favorite text editor and set the platform_version key to v2.4.1 as follows:

Step 2 – Check your module versions

Due to changes introduced by the new runtime permissions framework in Android 6.0 Marshmallow (API level 23) you may need to update your modules.

If you are using any of the following modules please ensure you are on the latest versions:

module version
contact 2.9
calendar 2.7
geolocation 2.4
camera 2.3
file 2.11

Step 3 – Develop!

To build your app against the new crosswalk target you can simply run:

Our android and ios targets remain unchanged.

Crosswalk options

We’ve also added two new optional configuration keys to src/config.json that control Crosswalk behaviour:

If you are experiencing rendering issues on some devices the disable_gpu_rasterization setting will work around bugs in their OpenGL implementations.

The disable_pull_to_refresh_effect setting allows you to disable Crosswalk’s default behaviour of refreshing the screen when the user “pulls-down’ on a page.

Check the documentation for more information.

In Conclusion

v2.4.1 is a massive release for us and represents the culmination of almost a year’s worth of engineering effort.

The complexity of integrating a new Forge runtime while simultaneously migrating our Android build system over to Gradle has been non-trivial and I’d like to give a special shout out to:

  • The v2.3beta branch testers who tirelessly hammered on each release, reported bugs and – often – contributed hours of their time to help us track down and reproduce issues. Y’all know who you are, thank you!

  • The Crosswalk team @ Intel. Crosswalk is beautifully engineered so it was rare that we got stuck, but when we did you were there with rapid responses, answers and marketing support!

Finally, if you run into any issues with v2.4.1 or have any questions about this release please don’t hesitate to get in touch with us at support@trigger.io.

Winding down for the year

Dear Trigger developers,

Well here we are again. The year is drawing to a close, there’s a definite festive spirit in the air and I’m wondering where the time has gone.

2015 has been a landmark year for Trigger.io and I’m pleased as punch to share that we are once again showing stable month-on-month growth. This marks the completion of the transitionary period from externally-funded startup
to a sustainable business and is a reliable indicator that we will continue to be here for all of you, now and in the future.

We wouldn’t have come this far without the willingness of the Trigger.io community to bet on us. So from our oldest customers who have been with us since we were in beta to our newest customers who only joined this week:

“Thank you, you rock!”

I’m not going to get into details on the engineering work we have planned for the new year as I covered it last month. Instead, I’d like to talk about the softer side of the platform.

Over the last couple of weeks I’ve heard from many of you with suggestions and questions about what 2016 holds in store. The dominant theme in all these conversations have been that it’s time for us to put energy and
resources into the Trigger.IO community.

Based on these conversations, some of the things we’d like to look at are:

  • Opening up the development processes around our open source native modules.
  • Making the knowledge accumalated in our support systems publicaly available.
  • Alternatives to stackoverflow.com for community support and communication.
  • Re-organising tutorials and other how-to information on our blog and website for discoverability.
  • Rebooting a sadly lapsed tradition of showcasing the work our customers are doing.

If you’ve also got ideas you’d like to share, please get in touch.

Finally, our offices will be shutting down on the 15th of December 2015 and will open again on the 7th of January. We will however have someone checking in on support during this time in case any emergencies come up.

Wishing everyone a fantastic holiday to recharge for the coming year, I have a feeling it’s going to be a great one!

All the best,
Antoine

Ch-ch-ch-ch-changes!

The road to 2.4


Update

v2.3.2beta-1 has now been pushed to production. Please check the changelog for details.


If you were to dig through our platform release notes you’d notice that it’s been nearly 18 months since the last major version number update to the platform.

During this time we’ve released 16 minor platform updates to help you navigate through:

  • Two major iOS software and hardware releases.
  • Support for writing custom native modules using the Swift programming language.
  • Four major Android API releases.
  • Beta support for Intel’s Crosswalk web runtime.
  • More App Store rule changes than anyone (including Apple) keeps track of.

I’ll be honest, surfing this tsunami of change isn’t always fun but once in a while I’ll come across something that reminds me of the value of what we do:

Legacy

I don’t want to get into a rant about the kind of thinking responsible for this state of affairs but I would like to place it in perspective:

If, twenty years ago, you compiled a C/C++ application for the Windows WIN32 API using C/C++ there is every chance that your original binary executable will still work on Microsoft’s latest Windows 10 release.

Binary compatibility is unfortunately out of our reach and it’s still too early to tell if Trigger.IO will match Microsoft’s track record but we’re certainly giving it the old college try.

Simply put:

If you shipped a HTML/CSS/JS Trigger.IO app in 2012 chances are very, very good that it will still run on the latest versions of iOS and Android without requiring anything more from your side than a forge build ios && forge build android.

Your legacy? It matters to us.

Platform Version 2.4

The road to 2.4 has been long and I know a lot of you have been patiently waiting for the Crosswalk support from our beta branch to finally make its way to stable release.

Well, I’m pleased to announce that today we finished the last major piece of work that has been holding this back!

Basically, we had two major blockers:

  1. The Ant build system had problems dealing with application resources from multiple external libraries which led to all kinds of horrible bugs when using Crosswalk with some native modules.
  2. There was no simple way to test custom native modules in both the Android and Crosswalk environments.

The resolution wasn’t simple but, ironically, it came in the form of the kind of announcement we’d normally dread:

As of next year Google will no longer be supporting Eclipse or the Ant build system.

It’s taken the better part of two months, but we’ve finished migrating our Android build system over to Gradle and it has brought a wealth of cool stuff, including:

  • Android Studio support for custom native module development.
  • Support for using .aar packages directly from your custom native modules.
  • Support for including module dependencies directly from Maven and other repositories.
  • Support for debugging modules against both Android and Crosswalk.
  • Support for building x86 and 64-bit packages for Android.
  • No more module resource conflicts!

We’ll continue to support Eclipse for as long as possible, but you may be surprised how easy (and pleasant!) it is to move your module development over to Android Studio.

Release Timeline

Migrating the Android build system is a massive change and, no matter how much testing we do on our side, there is still potential for things to break.

We’re now officially in feature-freeze for v2.4 and will be pushing v2.3.2beta-1 to production early next week.

Depending on how much feedback we get from y’all at support@trigger.io we’re hoping to pull the trigger on stable release before the end of the year.

Trigger.io Forge support for iOS9 and OSX “El Capitan” is ready!

Trigger.io Forge is ready for iOS9 and OSX El Capitan

If you caught last night’s Apple event you’ll know Apple have finally pushed the GM releases for Xcode 7, iOS 9 and OSX El Capitan.

The GM release is what Apple will be shipping to the general public in a week’s time so, if you haven’t been following along during the Beta-test phase, now is the time to make sure your app is ready for iOS 9.

We’ve been working towards this moment since the initial announcement in June and are pleased as punch to announce that Trigger.io supports iOS9 and OSX El Capitan as of platform version v2.2.16.

To get your app running on iOS 9 all you’ll need to do is take the following steps:

1. Upgrade your Xcode to version 7

You can grab the GM seed from the Xcode Developer Center or, if you don’t mind waiting a week, download the update from the App Store.

2. Update your iOS device to iOS 9 (Optional)

If you don’t want to wait till next week, you can head over to the iOS Developer Center and grab the install image.

We also support the new iOS 9 simulator in Xcode 7 so this step is not necessary if you want to hold off on upgrading your hardware immediately.

3. Update your app to platform version v2.2.16

To update your app to the latest platform version open up the Trigger.io Toolkit, navigate to your app config and click on the Change version button:

Toolkit App Config

In the popup dialog, simply click the Switch to v2.2.16 button:

Toolkit App Version

That’s it!

Feedback

Sometimes there are minor teething issues with GM releases as Apple often adds a bunch of new stuff that wasn’t present in the betas. So please, if you run into any problems or have questions, don’t hesitate to let us know at support@trigger.io and we’ll be all over it!

Important note for Ionic/Angular users:

We’ve heard reports that UIWebView for iOS 9 introduced a breaking change that can cause issues for apps that rely on the semantics of window.location.

If your app uses the Angular $location service you can find a patch and more information here:

http://blog.ionic.io/ios-9-potential-breaking-change/

Shipping Code with Trigger.io Forge
Part 2: Choose Your App Architecture

header

Welcome to the second part of our new monthly blog series, “Shipping Code”!

In the previous instalment we took a look at the various strategies available for developing your mobile app. We covered Mobile Web Apps, Native Apps and Hybrid Apps.

For the remainder of the series we’ll be leaving Web & Native Apps behind to focus purely on Hybrid App development because that’s what we do here at Trigger.io!

How should I structure the architecture of my Hybrid app?

Now that you’ve decided on a Hybrid App for your development strategy the next question you’ll face is how to structure your code.

There are a variety of architectural patterns in common use and the approach you decide on will depend largely on the type of application you are developing.

In general terms we can break the patterns down into the following broad categories:

  • Single Page: The “Single Page” architecture is the most common pattern found with hybrid apps. This architecture takes the form of a single index.html page which serves as the containing document for the app. Content and resources are then dynamically loaded into this page via Javascript.
  • Static Site: The “Static Site” architecture is similar to a traditional web site. The app consists of multiple HTML pages which are linked together via hyperlinks.
  • Hosted Iframe: In the “Hosted Iframe” architecture the app takes the form of a single index.html page with an embedded <iframe/> tag which contains a remote web site.

Let’s take a closer look at each of these patterns:

Option 1: Single Page

single-page architecture

The trend over the last ten years has been towards so-called “Single Page” apps which move responsibility for rendering the application UI from the server towards client-side HTML and Javascript.

This approach brings a number of advantages, most importantly:

  • Speed: With traditional server-side architecture there is a significant delay after each user interaction as a request first has to be sent to the server and any UI updates have to be returned to the user.
  • Simplicity: Rather than managing complex application and UI state on the server for each user, that state can now be maintained locally on the user’s device.

See the Wikipedia page for a thorough discussion on Single Page applications.

While the entire app is hosted on a single page local to the device the backend web server still plays a role. Most commonly, a RESTful JSON interface will be exposed on the web server which provides the following services to your app:

  • Implementing application logic for the data endpoints used by the application.
  • Retrieval and persistence of application state.
  • User authentication and authorisation.

The components of a Single Page App

The exact structure of your Single Page app will depend largely on whether you are using vanilla HTML/Javascript/CSS or one of the many Third-party Single Page app frameworks to implement your app.

That said, most Single Page apps will contain some combination of the following elements:

  • A src/index.html file containing:
    • The basic app layout
    • Imports for your Javascript code.
    • Imports for your CSS code.
    • Imports for any Third-party Javascript & CSS libraries.
  • One or more src/templates/*.html files containing:
    • Templates for your views
    • Templates for your UI components
  • One or more src/js/*.js files containing:
    • Your application logic.
    • Third-party libraries and frameworks.
  • One or more src/css/*.css files containing:
    • Rules for the look & feel of your application.
    • Third-party CSS frameworks.
  • Binary resources such as images, audio or video.

Third party Single Page App Frameworks

There are a large number of Third-party Single Page libraries and frameworks available that simplify the task of structuring and developing your Single Page app.

While the borders aren’t always clear-cut, we can divide Single Page app Frameworks into two broad categories:

  • Application Frameworks: Provide functions to handle app navigation (routing), template rendering, user event processing and data-binding between the application’s data and user interface elements.
  • User Interface Frameworks: Provide User Interface elements such as buttons, lists, popovers, transitions etc. that mirror the functionality (and sometimes also the look & feel) of native apps.

Some examples for each type of framework are:

Application Frameworks

User Interface Frameworks

Figuring out which framework will work best for your purposes can be a complex endeavour and is a topic we’ll cover in-depth with our next instalment.

Pros for Single Page Architecture

  • Provides a fluid user experience with complex interactions comparable to Native Apps.
  • It’s much easier to develop complex Single Page apps than traditional server-based applications.
  • There is a huge selection of high-quality Third-party Single Page app frameworks available.
  • You can access all forge.* API’s from your app.
  • Users can still use your app even if they are not connected to the Internet.

Cons for Single Page Architecture

  • If you have not developed Single Page apps before you’ll have to go through a mild learning curve to get comfortable with the concepts.
  • If you want to use functionality from your existing website you may need to implement a RESTful JSON interface for transferring data between your app and backend services.

Option 2: Static Site

static architecture

This approach can work well with simple apps that require interaction with native device features and consist primarily of statically served web pages, images and other resources.

The components of a Single Page App

Structured in the same way as a website serving static content, your hybrid app contains a separate HTML file for each page in the site.

While it’s tempting to think you could take any existing website and easily convert it to a web app in this way it’s worth remembering that this will only work with the very simplest of sites as you will no longer be able to rely on the server for processing user interaction or other forms dynamic processing.

Pros for Static Site Architecture

  • It can be the easiest way to transfer content from an existing site to mobile.
  • You can access all forge.* API’s from your app.
  • Users can still use your app even if they are not connected to the Internet.

Cons for Static Site Architecture

  • Maintaining a complex application as a set of HTML pages can quickly become overwhelming.
  • If your existing site features complex server interactions you will have to rewrite those as client-side Javascript and expose a RESTful JSON interface on your server.

Option 3: Hosted Iframe

hosted iframe architecture

If you have an existing web app which does not require complex interactions with native device features or functionality you can simply “host” it inside a hybrid app by using an <iframe /> HTML tag inside your app’s main page.

An important factor to bear in mind is that you cannot directly access forge.* API’s from the remote site’s pages.

If you would like to make use of native device features you will need to bridge the calls from the remote page to your app’s src/index.html page by using the window.postMessage() and window.addEventListener() API’s to marshall communication between the hosted site and the parent hybrid app.

A Simple Example

The code for the remote page, hosted on the remote server:

The code for your app’s src/index.html page:

Pros for Hosted Iframe Architecture

  • You can re-use portions of your existing site’s functionality.
  • You can decide which portions of your app will be implemented locally and which portions will re-use existing site functionality.

Cons for Hosted Iframe Architecture

  • You will need to apply responsive design to your remote content or it may look odd on mobile devices.
  • Accessing device functionality through the forge.* API’s is more complex as function calls will need to be marshalled through the iframe’s parent window.
  • Users may not be able to use your app unless they are connected to the Internet.

Conclusion

All of the above options are supported by Trigger.io Forge but we will be spending the bulk of our time in this series focusing on the Single Page App Architecture (Option 1) as it has emerged as the most practical and popular pattern for hybrid app development.

In the next instalment of this series we’ll be taking a closer look at some Single Page app frameworks and the problems they solve.

Until then, if you have any questions about the material we’ve covered so far, we’d love to hear from you at support@trigger.io!

Using OAuth 2.0 and the Google API Client Library for Javascript with Trigger.io Forge

Introduction

Google’s beta release of their API Client Library for Javascript promises to make life easier for developers who want to integrate their apps with Google services (Calendar, Contacts, Analytics, etc.)

While Google provide some documentation for using their library with web applications accessed via a standard browser there are some gotchas involved when trying to make us of it in a Hybrid app environment.

Specifically:

  • Athentication & Authorization flow differs slightly as Hybrid apps do not support the creation of popup windows.
  • Google make use of a small shim library which bootstraps the rest of the library source code from their remote servers. This library has a bug which causes it to fail silently when included from a page which has been served by a protocol other than http:, https: or file:. Unfortunately, Trigger.io app assets are served via the content: protocol on Android!

In this technote I’m going to show you how to use the GoogleJS Client Library and walk through solutions to both of these issues.

Application Configuration

To follow this tech note and use the Google Javascript client library, you’ll first need to configure your application as follows:

Step 1: Platform Version

Make sure your app is running on platform version v2.2.15 (or higher)

Step 2: Modules

Add the following three modules to your app:

  • tabs – We’re going to use a forge tab to open the OAuth authorization dialog and obtain the user’s auth token for your app.
  • httpd – This is a new, experimental, module which serves your app content via the http: protocol rather than file: (iOS) or content: (Android).
  • parameters – We’re going to use the parameters module to store your Google API keys.

Step 3: Trusted URL’s

In your app config, go to core => general => trusted_urls and add the following entry:

This will whitelist any requests made to the httpd module and ensure they are opened by your app’s webview rather than the device browser.

Obtain Google API keys

Before you can use the Google Javascript client library you’ll need to register your app and create a set of API keys.

You can find full instructions here but the process boils down to the following steps:

  1. Visit the Google API’s Console
  2. Create a project for your application.
  3. Navigate to: API's & auth => APIs
  4. Select the API’s you want to use and enable them.
  5. Navigate to: API's & auth => Credentials
  6. Create a new OAuth “Client ID” with the following settings:
    • Application type: Web application
    • Authorized Javascript origins: http://localhost
    • Authorized redirect URIs: http://localhost/oauth2callback
  7. Create a new Public API access “Key” with the following settings:
    • Key type: Browser key
    • HTTP referrers: Leave empty

Once you’ve created the keys, you can add them to your app by adding the following entries to the parameters module:

Loading the Google client library

To load the Javascript client library, include the following script tag in your app’s src/index.html file:

You’ll notice that the script takes a single argument: onload=OnLoadCallback

This specifies the name of a Javascript function in your code that will be called once the library has finished loading and is ready for use.

To implement the callback, add the following global function definition to your code:

Depending on how your app is structured you can use this callback in a number of ways, including:

  • Setting your Public API access key.
  • Letting the rest of your app know that the library has loaded and ready for use.
  • Logging in the user for API’s which require OAuth login credentials.
  • Checking that cached OAuth login credentials are still valid.
  • Loading the Google API libraries your app will use.

Performing Public API requests

For Public API requests the only authorization you’ll require is to set your API key in the library onload callback.

To keep downloads to a minimium Google have implemented an incremental loading mechanism for the client libraries.

To use a particular library you will first have to load it by making a call to gapi.client.load(API_NAME, API_VERSION, CALLBACK).

Once the library is loaded you will be able to access it directly using the format: gapi.client.API_NAME.FUNCTION

For example, the following code can be used to return public information for a Google+ user:

Note that you only ever have to load a libary once via gapi.client.load.

For more information you can refer to the Google documentation.

OAuth 2.0 Authentication & Authorization

To access any private data belonging to the user your application will need to work with Google’s OAuth 2.0 mechanism.

While Google provide a simple convenience method in the form of gapi.auth.authorize() it is not suitable for use in a Hybrid application as it will attempt to open a browser popup window to handle user login.

Fortunately it’s easy enough to write our own OAuth function using the tabs module:

Note that this method is not only limited to Google but can also be used for any other OAuth service!

Our OAuthorize funtion takes an options object as an argument with the following fields:

  • url – the remote OAuth end point. In this case we’ll be using Google’s.
  • client_id – the OAuth Google Client ID you signed up for earlier.
  • redirect_uri – the URL to redirect the OAuth popup to after the user has authenticated. Here we will use the value we used earlier when we created our Google Client ID.
  • scope – the scope of the authorization we’re requesting. For now we’ll just limit this to the user’s basic information on Google Plus.

To authenticate our App with Google and obtain an authorization token we can use to configure the Google client library we’d use the function like this:

Now we can make Google API calls that will return user information:

…and that’s a wrap!

For more information on Google’s OAuth mechanism please refer to the Google documentation.

Conclusion

I hope you’ve enjoyed this quick walkthrough on using Google’s Javascript Client Library with Trigger.io Forge. As always, we’re looking forward to your questions or comments at support@trigger.io!

Shipping Code with Trigger.io Forge
Part 1: Choose Your Mobile App Strategy

header

Series overview

Part of what attracts developers to hybrid apps is the freedom of choice we get from building on open standards supported by the community of our fellow developers but this very freedom can also be intimidating at times!

To help make sense of the wild and wooly landscape out there we’d like to introduce our new monthly blog series: “Shipping Code”

Our “Shipping Code” series will be running over the next year and will cover the entire hybrid app development cycle from beginning to end.

The process of shipping a new mobile app from scratch is complex and you’ll run into many different questions on your journey.

What we will try and do is to fit those questions (and some answers!) into a cohesive picture which, we hope, will assist both new hybrid developers and even old hands to locate themselves in the happy chaos of modern mobile app development.

Introduction: The Three Mobile App Strategies

As a developer you have three broad strategies available to you if you want to develop an app which runs on a mobile device:

  1. Mobile Web App
  2. Native App
  3. Hybrid App

We’ll be kicking off our series on hybrid app development by examining some of the pros and cons of each approach.

Strategy 1: Mobile Web App

The easiest solution for getting your application onto a mobile device is to simply develop it as a web application.

Web App

Mobile web apps are hosted on a remote server and built using identical technologies to desktop web apps: HTML5, JavaScript and CSS

The primary difference is that it will be accessed via mobile device’s built-in web browser which may require you to apply responsive web design principles to ensure that the user experience is not degraded by the limited screen size on mobile.

There are a number of limitations to this approach but the biggest is that you will only have limited access to device API’s, features and integration with other apps on the user’s device.

Pros:

  • Few, if any, technological differences from any other web site or web application.
  • Maintain a single version of your app for both mobile and desktop versions.
  • You can easily ship new versions of your app by updating the remote server.

Cons:

  • The cost of applying responsive design principles to an existing website may be a significant fraction of developing a mobile app.
  • Your app will not be available on mobile app stores which may make it hard for users to find it.
  • Mobile device browsers have historically lagged behind their desktop counterparts, this can create compatibility issues on mobile devices with parts of your app not behaving as required.
  • Limited access to device features.

Strategy 2: Native App

Native Apps exist on the other extreme of the scale. They are developed using the device’s native SDK’s.

Native App

On Android this usually means writing your code in Java using Google’s Android SDK libraries. On iOS you’d be working in Objective-C or Swift using Apple’s iOS SDK libraries.

This is unquestionably the most powerful approach as you are able to access all features of the device and make use of the native UI components of the device.

The biggest downside is that you’re going to need engineers with the skills required to maintain two separate platform versions of your app, one for each device you want to support.

Pros:

  • Access to all device API’s, features and inter-app integration.
  • Full control over the user experience allowing for complex experiences such as gaming or content creation.
  • Your app will match the native look & feel of the device without requiring a 3rd-party UI library.
  • Your app will be available on App stores.

Cons:

  • Development costs are high and can take orders of magnitude longer to ship due to the low-level nature of the device SDK’s.
  • You need to write and maintain a separate version of your app for each device you want to support.
  • Developers need to learn multiple different programming languages and API’s with steep learning curves for each version of the same app.
  • Slower development time.
  • Bugs are more likely to crash your app (or even the device!)
  • Harder to debug errors & crashes
  • Shipping updates can be slow due to the app store approval processes.

Strategy 3: Hybrid App

Hybrid apps occupy the space in the middle of the previous two extremes. They enable you to use standard web technologies to develop your app whilst, simultaneously, having access to the native API’s and features of the device.

Hybrid App

While they have somewhat of a reputation for not being competitive against their native counterparts the present reality is that we continue to see more and more world-class apps that shipped with a Hybrid App strategy.

There are many more good reasons to choose a Hybrid App for your project but there’s one factor which stands out above all else:

Shipping and maintaining a Native App on both Android & iOS is going to cost you, at the very least, twice as much as a Hybrid App.

…and this is assuming that you and/or your team are already well versed in Java, Objective-C, Swift and the Android & iOS SDK’s!

Pros:

  • You can use most of the same technologies and tools used for web development to create a mobile app.
  • Maintain a single codebase for both iOS and Android versions of your app.
  • You can re-use many components of any existing web apps you may have.
  • Your app will be available on App stores.
  • Easily ship updates to your app without requiring App Store approval with Trigger.io Reload.
  • Access to device API’s, features and application integrations via native modules.
  • Modern web-technologies such as CSS Transitions and WebGL allow you to achieve near-native UI performance even for complex user interactions.
  • Excellent development tools courtesy of Chrome & Safari remote debugging.

Cons:

  • Achieving a native look&feel depends on 3rd party frameworks which may vary in quality.
  • There are many different ways of doing things and it can be hard to know which approach to follow up front.
  • App performance can suffer if you are not conscientious.
  • Accessing some native device features may still require you to write portions of your app in native code.

Conclusion

In this, the first instalment of our “Shipping Code” series, we looked at the pros & cons of the three strategies for mobile app development: Mobile Web App, Native App and Hybrid App.

In the next instalment of this series we’ll be taking a look at the different architectural choices you need to make when developing your Hybrid App.

Until then, if you have any questions about the material we’ve covered so far or suggestions for future instalments, we’d love to hear from you at support@trigger.io.