Another splendid year at Trigger.io

Hi Trigger Folk,

Following a turbulent start at the beginning of the year our team have had the time of their lives delivering ongoing product development and world class support for your favourite hybrid app platform.

And what a twelve months it has been… over the course of this year we:

  • Resolved 1787 support tickets.
  • Released 80 module updates including support for major SDK updates from Facebook, Parse, Flurry, UrbanAirship and Apptentive.
  • Released 17 platform updates including support for iOS 8 and Android 5.0
  • Released Forge Live and sped up everyone’s development workflow by an order of magnitude.
  • Released our entire catalogue of native modules as open source.
  • Began building a community of contributors to our open source modules. Thank you for everyone who sent in a push request or three, you know who you are!
  • Introduced you to the future of hybrid app UI’s with our introduction to Famo.us with sloths
  • Worked with the great folk at PushWoosh to bring you another option for Push Notifications on Android and iOS.

I’d like to say a special thank you to so many of our customers who have been incredibly supportive, patient and just plain awesome during this time. Without you it would never have been possible to successfully transition Trigger.io to become independent, profitable and able to remain this way!

The team will be taking a well-deserved break starting from this Monday, 22 December till Wednesday, the 7th of January 2015. We will however be responding to any critical issues that may come up during this time.

This email wouldn’t be complete without a hint at some goodies Santa has in store for us in 2015 so I’ll just say: Thisthis, some of this and definitely more of this.

All my thanks to our customers, business partners, StackOverflow contributors, module authors, GitHub contributors, contractors and everyone (past and present!) at Trigger. We wish you all a peaceful holidays and a truly satisfying new year!

 - Antoine

Ridiculously fast Trigger.io app development with Forge Live

Today we released v2.1.7 of the Forge platform and with it, a major new feature we’re really excited about: Forge Live

 

Forge Live shows you the effect of your code changes in real-time on an emulator or device making the the mobile build / deploy / test cycle faster than even the web (you don’t need to refresh!).

See it in action now:

Background

It’s almost halfway through 2014 and there’s never been a better time to be hybrid app developer.

Frameworks such as AngularJS, Ionic and React promise an order of magnitude improvement in developer productivity. Coming up we can also look forward to technologies such as Famo.us, WebGL and Apple’s Nitro JavaScript engine. Technologies which promise a level of performance that will open up a whole new class of applications that could previously only be tackled by native developers.

That said, one thing that doesn’t seem to be receiving much love is mobile app development workflow.

Frankly, writing apps for iOS or Android feels much like desktop app development did in the early 90′s!

  • Write some code
  • Compile your app
  • Deploy to device
  • Run app
  • Wash. Rinse. Repeat.

While this model is not without its advantages  it’s a shame to be bound by limitations inherent to compiled languages such as Java and Objective-C when hybrid app development is built on the same dynamic languages that make web development as easy as:

  • Write some code
  • Hit Refresh

In fact, using tools such as grunt-contrib-watch to detect changes to your files and then automatically trigger a browser reload the entire cycle can be reduced to a single step.

That’s why we created Forge Live!

Using Forge Live

Note:

If you are developing for Android please note that Forge Live is only supported on devices running Android KitKat (4.4.x) or higher.

Step 1: Install Node.js

Before you can start using Forge Live you will first need to install Node.js on your machine. You can either use your favourite package manager or download an installer from: http://nodejs.org/download/

Note:

On newer versions of Ubuntu the packaged node binary has been renamed to nodejs due to a conflict with another package. Unfortunately this has the side-effect of breaking grunt.

The workaround is to install the nodejs-legacy package as follows:

sudo apt-get install nodejs-legacy

Step 2: Check your Platform Version

If you’ve just created a new app you won’t need to do anything here.

If you want to use Forge Live with an existing app you will first need to check that your app is compiled with Forge 2.1.7 or higher.

You can do this from within the Trigger Toolkit:

Or in your src/config.json file:

Step 3: Start your app

Once your app is on the latest stable platform version you are ready to start your app up in Forge Live mode.

To do this, simply navigate to the Forge Actions page and click on the platform you’d like to work with:

Or with the command-line tools:

forge build ios

Followed by:

forge serve ios

Any changes you make to your source code will now be instantly reflected in your running app. It’s that easy!

If you’d like more information about using Forge Live you can also look at the documentation.

We’d love to hear what you think about Forge Live so please feel free to contact us on support@trigger.io with any questions or feedback.

A new year with Trigger.io

Ho Trigger Corps!

It’s now been just over two months since I took over the role of day-to-day management at Trigger.io and it’s time to take stock of what we’ve accomplished during this time.

This year I’ve had a chance to meet many of you for the first time and I’m pleased to report that we’ve been able to keep the promise we made to maintain the high bar Trigger.io sets for customer support. It’s been 75 days and during this time you’ve opened 420 support tickets and we, in turn, have resolved 425 support cases.

That said, despite all odds, life at Trigger.io hasn’t just been about support.

We’ve also managed to keep product development ticking over with 2 minor platform updates, 2 new native module releases and more than 10 updates to our existing native module line-up.

After open-sourcing our modules in December last year we’ve noticed a steadily increasing stream of pull requests coming in to the repositories that benefit our entire Trigger.io community.As a result it is largely due to your effort that we’ve been able to keep Trigger.io development moving.

Thank you Trigger Corps, You rock.

-Antoine

 

New Native Modules

 

Native Module Updates

  • forge.notification v2.3 New method: getBadgeNumber
  • forge.launchimage v2.4 New option: background-size: cover, iOS7 fixes
  • forge.file v2.3 New method: file.info()
  • forge.parse v2.3 New methods: setBadgeNumber, getBadgeNumber, registerForNotifications, Added support for Google Cloud Messaging, Update to latest Parse SDK
  • forge.flurry v2.4 New option: debug, Update to latest Flurry SDK
  • forge.facebook v2.3 Update to latest Facebook SDK
  • forge.media v2.2 Fix for mute switch position being ignored. (Thanks @mnaughton !)
  • forge.request v2.5 Fix HTTP method and contentType settings being ignored for file uploads
  • forge.contact v2.3 Fix a crash when selecting all contacts on Android

Read the full changelog here

 

Core Platform Updates

We’ve pushed out two minor updates to the core platform which brings us up to v2.1.2.

These updates fixed a number of annoying bugs, made some progress towards a better code signing experience for our Windows customers, brought our Android native API support up to android-19 and added Chrome DevTools remote debugging support for Android KitKat devices.

If you’re not already on 2.1.2 do consider updating your projects today!

Read the full changelog here

New Hires

I’m really pleased to announce our new team member, Gaelin Meyer, who has been doing a great job managing Accounts and Marketing for us here at Trigger.

Gaelin has been working in an advisory capacity with several Internet Startups here in Cape Town since 2005, holds a degree in Psychology from the University of South Africa and is busy raising two beautiful children.

Her primary responsibility is to know what you need from us at Trigger.io, so expect to hear more from her in the upcoming months!

 

Team changes at Trigger.io

Trigger.io is now nearly 3 years old and publicly available since January 2012. We’re delighted with how it has grown from a useful product — 10,000 developers signed up, and millions of app builds — to become a profitable business as of September this year.

We’re proud of the self-sustaining community that has built up around Trigger.io, with several people making their livelihood building apps for clients on our platform, and contributions from the community on StackOverflow. Last week we open-sourced our native modules and can already see developers begin to contribute.

At this point, James and I have made the decision to step back from day-to-day work on Trigger.io, and for the company to bring in new blood. Antoine van Gelder, whom many of you already know, will take over day-to-day management and new development.

We’re delighted to have Antoine take this on and anticipate only positive changes for current and new customers — there is no change to the availability of the Trigger.io service, support or plans for new development. James and I will continue to be involved as directors working with Antoine to improve the company and product, although you’ll see less of us in day-to-day communications.

Antoine

 

We’ve worked with Antoine for almost as long as Trigger.io has been around. He was instrumental in getting the product to launch, working across our entire stack from the client SDKs, Toolkit, server-side logic and compile servers. In addition to his development work, he has also interacted with many customers through support and through the maintenance of our legacy browser add-on platform.

Not only that, but Antoine has broad experience running all aspects of software companies having built his own startup and run consulting companies in the past. He’s a keen advocate of standards, open source and creating great products that benefit with the world. All that — combined with his technical expertise, knowledge of the Trigger.io stack, and product philosophy — means we are supremely confident that he is the right person to take Trigger.io from here.

With our v2.1 release we felt the company and product are in great shape and could benefit from new inspiration, so the time is right to pull the trigger (pun intended). Anyone who has worked on the same product for several years will know that it can often benefit from a new perspective, so we’re confident that the plan we’ve put together with Antoine is a win all around.

The future

James and I delight in creating new products and businesses which is why we started Trigger.io. We love what we’ve built with Trigger.io but over the past year have also become excited about other projects.

Specifically — based on many shared interests — James, Tim, Connor, and I have decided to join Square. We’re super excited about Square’s prospects, their team, and the new projects that we can impact there. Making commerce easy — Square’s mission — is inspiring and has many facets. We hope to iterate fast and be able to share more of what we’re working on soon.

We’re delighted at being able to make this team change while having the Trigger.io product continue to improve and grow sustainably. It’s a situation that few startups are able to reach, and we owe it all to our amazing customers: thank you!

Please do reach out by emailing support@trigger.io with your questions.

Trigger.io Forge 2.1: open-source modules and collaborative development

Today, we’re really excited to announce version 2.1 of Trigger.io’s mobile development platform: Forge.

This version is hugely significant for us, as it marks a shift towards a more open, collaborative development approach on the platform. As part of this, Trigger.io is open-sourcing the native modules that we’ve developed.

Since we launched our native modules feature at the end of July, we’ve been blown away by our users’ enthusiasm for adding new native functionality to your Trigger.io apps. Already, there have been over 1300 updates to the almost 400 modules our users have been working on, including modules for Urban Airship, Apptentive and keyboard customisation:

Three 3rd party modules

With version 2.1, we’re doubling down on native modules by making it super-simple to publish, consume and collaborate on native modules. Changes include:

  • ability to publish modules into the Trigger.io module index
  • introduce concept of module namespaces, which allows independent developers to collaborate on one codebase
  • dependency declaration and resolution between modules, so you can rely on a library being present without inlining it
  • add changelists and documentation for your module

Open-source

We’ve wanted to open source our modules for a long time, but before now there hasn’t been much point because it would have been so hard for our users to take our code and set themselves up to develop on it.

With the changes described above, those restrictions are now gone, and we’re excited to announce that we are open-sourcing all of our own native modules under the 2-clause BSD license.

If you want to tweak the form or function of a Trigger.io-created native module (e.g. customising the gradient of our topbar module, or extending our file module to capture audio as well as video), you can clone our code from GitHub and make the changes you want in your own module.

You can keep that module un-published — meaning only you and your team-mates can use it — or you could publish the updated module so everyone benefits. Of course, we’ll always appreciate pull requests back to our repo so that we can update the original module when it makes sense!

Note that we’re not open-sourcing everything. Our cloud build service, toolchain, and the core of our platform will remain under wraps: this means you won’t be able to do local-only builds that don’t use our cloud build service. But we firmly believe that the huge usability, speed and collaboration benefits you get from using a cloud-based compiler easily make up for that.

How to get involved

If you’re an existing Trigger.io user, our v2.1 update is rolling out now and you’ll be prompted to update shortly. If you’re not at the stage of creating native modules just yet, note that v2.1 includes a small change to JavaScript behaviour documented in the release notes.

Otherwise, head across to our site to create an account, download our lightweight tooling, and get started on your first app.

The native module development process is covered in our documentation, and keep your eye on GitHub — we’ll be uploading and updating our module code there!

New feature roundup: iOS 7 and Android 4.4 support, new accelerometer and Apptentive modules

As well as a host of minor improvements and fixes which are documented in our module changelog, we’ve been hard at work on some big items.

Namely, support for new iOS and Android platform versions and two new modules: one developed by us, another by a 3rd party which we’re delighted to be able to offer.

Here are the details:

Apptentive: in-app feedback from your users

Apptentive provide SDKs for iOS and Android that enable you to get in-app feedback from your users.

Interacting with your users inside your app is immensely important to boost ratings – create conversations rather than critics and intercept negative feedback. So we’re really excited that they’ve created a Trigger.io module so you can use their SDK in your Trigger.io app:

forge.apptentive.showMessageCenter(
    {},
    function(error) {
        forge.logging.info("Error: " + error.message);
    }
);

This example shows how Apptentive can be used to solicit feedback. In addition, the Apptentive module provides:

  • App Store rating flow
  • Surveys
  • Custom user information tracking
  • Custom device data tracking

We’re excited for future updates by Apptentive and other SDK developers who integrate with Trigger.io.

Accelerometer module

By popular demand, we’ve created an accelerometer module. Here’s an example of how it can be used to detect whether the phone is laying flat:

// Alert the user the first time they put their device on a flat surface
forge.accelerometer.onChange.addListener(function (data) {
	if (data.z > 9 && data.z < 11) {
		forge.accelerometer.clearWatchInterval();
		alert("Phone is flat");
	}
});
forge.accelerometer.setWatchInterval(1);

iOS 7 and Android 4.4 support

We released support for iOS 7 in September as part of our v2.0.1 platform version, with several new module versions. You can read details of the changes here.

More recently, we were very excited about Android 4.4 (KitKat) which was released last week. Especially since this new version of Android will have its WebView powered by Chromium. That’s great news for developers since it means that, in Trigger.io apps built for Android 4.4, you can use:

To start building for Android 4.4, you will need to:

  1. Rebuild with our latest platform version – 2.0.4
  2. Update tabs module to 2.5
  3. Update ui module to 2.1

What’s next?

Follow us on Twitter or Facebook to see our latest news and updates.

Sign up now to take advantage of these new features or get in touch with us at anytime at support@trigger.io.

Guest post – how CardSmith build for mobile using Trigger.io

This guest blog post was written by Scott McClure, developer at CardSmith, currently building the mobile version of their access, tracking, and verification application using Trigger.io. He also manages the build and release processes for the company. 

About the app

PockeTracker is a mobile application that allows users to verify admittance to facilities and events, take payments on location, and track attendance. It supports an offline mode and the ability to scan ID cards with magstripe, barcode, or contactless card readers. Version 3.0 of the application was redesigned from the ground up using Trigger.io.

Why Trigger.io?

We had several specific requirements for the tools needed to build the next generation of our mobile application.

  1. We wanted to write the majority of the code in a language everyone on the development team was familiar with.
  2. We needed to be able to target both iOS and Android platforms.
  3. If we were going to use a hybrid model approach we would still need direct access to the underlying OS. Direct access was particularly important because the application needed to integrate with several different magstripe, barcode, and contactless card scanners, and keyboard emulation would be insufficient to accomplish this. Also, we were going to need to support an offline mode with large amounts of data being cached locally. We felt for performance reasons that this should be implemented natively.
  4. Any tools required for building and packaging the application needed to integrate seamlessly into our current build process.

Trigger.io fit all of these requirements and we have been very pleased with the final results.

I’d like to share with you how we accomplished the last requirement to integrate with our current build process.

Build Process

For all of our applications, we rely on Subversion for source control and TeamCity for build management. With PockeTracker, we now also use the standalone build API provided by Trigger.io. Source code check-ins are automatically detected by TeamCity, then checked out by the build agent and sent via HTTP to the Trigger.io standalone build service.

We could have just as easily used the Trigger.io command line tools instead of the standalone API, but using the API gave us one less build agent dependency to maintain.

Currently, our build tasks include:

  1. Check out the latest source from the trunk
  2. Run our JavaScript modules through the Require.js optimizer
  3. Update the build number in the config.json file
  4. Zip the source folder
  5. Send the zip to the Trigger build service
  6. Monitor the build for a success or failure
  7. If successful, download the package and publish it

Checking out

This isn’t really a post about how to set up a TeamCity build configuration, but TeamCity makes it very easy to monitor a Subversion repository for changes and check out the updated source onto a build agent. It simply requires you point TeamCity to your repository, add your login information, and create a build process trigger.

Updating the build number

Once a change is detected and the source downloaded, we need to update the version number found in the config.json configuration file. Using a custom C# build runner plugin, and taking advantage of the JavaScriptSerializer class we are able to accomplish this fairly easily:

const string PATH = @"%teamcity.build.checkoutDir%/src/config.json";

JavaScriptSerializer serializer = new JavaScriptSerializer();
var jsonObject = serializer.DeserializeObject(File.ReadAllText(PATH)) as Dictionary;
jsonObject["version"] = "%MajorBuildNum%.%MinorBuildNum%.%RevisionBuildNum%";
File.WriteAllText(PATH, serializer.Serialize(jsonObject));

Zipping the source

Once the build number is updated, we use the NAnt runner to zip the contents of the ‘src’ folder:

<?xml version="1.0" encoding="utf-8"?>
<project name="RapIDTrack 3 Client" default="build" basedir=".">
  <target name="zipME">
    <zip zipfile="%system.teamcity.build.checkoutDir%\src.zip">
      <fileset basedir="%system.teamcity.build.checkoutDir%\src">
        <include name="**.*" />
      </fileset>
    </zip>
  </target>
</project>

Push, monitor, and download

Out last steps are to push the zip file to the Trigger standalone build service, monitor for a successful build, and download the package. Again, we used the C# build runner.

To push the zip file along with some configuration settings, we prepare a web request. Since we are currently only building for Android, we only need to include the required email, password, and ‘and_*’ fields.

const string boundary = "---------------------------AaB03x";
const string url = "https://trigger.io/standalone/package";
const string email = EMAILADDRESS
const string password = PASSWORD;
const int MAXTRIES = 500;
const String DLDIR = @"%teamcity.build.checkoutDir%";
const String BUILDNUM = @"%build.number%";

Dictionary<String, String> nameValues = new Dictionary<string, string>();
Dictionary<String, String> namePaths = new Dictionary<string, string>();

nameValues.Add("email", email);
nameValues.Add("password", password);
nameValues.Add("and_keypass", ANDROIDKEYPASS);
nameValues.Add("and_storepass", ANDROIDSTOREPASS);
nameValues.Add("and_keyalias", ANDROIDKEYALIAS);
namePaths.Add("src_zip", @"%teamcity.build.checkoutDir%\src.zip");
namePaths.Add("and_keystore", @"%teamcity.build.checkoutDir%\ + ANDROIDKEYSTORENAME");

HttpWebRequest req = (HttpWebRequest)WebRequest.CreateHttp(url);
req.Timeout = 300000;
req.Method = "POST";

req.Accept = "application/json";
req.ContentType = String.Format("multipart/form-data; boundary={0}", boundary);

StringBuilder body = new StringBuilder();
using (System.IO.Stream s = req.GetRequestStream())
{
	foreach (String name in nameValues.Keys)
	{
		String line = String.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", boundary, name, nameValues[name]);
		byte[] buff = Encoding.UTF8.GetBytes(line);
		s.Write(buff, 0, buff.Length);
	}

	foreach (String name in namePaths.Keys)
	{
		String line1 = String.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\";filename=\"{2}\"\r\nContent-Type: application/base64\r\n\r\n", boundary, name, Path.GetFileName(namePaths[name]));

		//stream the description
		byte[] buff = Encoding.UTF8.GetBytes(line1);
		s.Write(buff, 0, buff.Length);
		//stream the file
		buff = File.ReadAllBytes(namePaths[name]);
		s.Write(buff, 0, buff.Length);
		//stream end
		buff = Encoding.UTF8.GetBytes(Environment.NewLine);
		s.Write(buff, 0, buff.Length);
	}

	//end our form data
	String endLine = String.Format("--{0}--", boundary);
	byte[] endBuff = Encoding.UTF8.GetBytes(endLine);
	s.Write(endBuff, 0, endBuff.Length);
}
...

Next we send the POST request and get the response:

using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) {
	if (resp.StatusCode == HttpStatusCode.OK)
	{
		//GOOD response should be in the form of:
		//{"id": "SOME GUID HERE", "result": "ok"}
		//BAD response will be:
		//{"errors" { JSON ARRAY OF ERRORS } }

		StringBuilder sb = new StringBuilder();
		using (StreamReader r = new StreamReader(resp.GetResponseStream()))
		{
			while (!r.EndOfStream)
				sb.Append(r.ReadLine());
		}//end using
		String response = sb.ToString();

		JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
		var pushResult = jsSerializer.DeserializeObject(response) as Dictionary<string, object>;
		if (pushResult.ContainsKey("result") && String.Compare(pushResult["result"].ToString(), "ok", true) == 0)
    ...

If the response is OK, we periodically call the service with the ID that was supplied to monitor the build progress:

String id = pushResult["id"].ToString();
Console.WriteLine(String.Format("Response Success, ID is: {0}", id));
Console.WriteLine("Monitoring Build...");

//monitor the build by periodically asking if the build is complete, using id
String askURL = String.Format("https://trigger.io/standalone/track/package/{0}?email={1}&password={2}", id, email, password);
int count = 0;
while (count < MAXTRIES)
{
	HttpWebRequest askReq = WebRequest.CreateHttp(askURL);
	askReq.Method = "GET";
	using (HttpWebResponse askResponse = (HttpWebResponse)askReq.GetResponse())
	{
		sb = new StringBuilder();
		using (StreamReader r = new StreamReader(askResponse.GetResponseStream()))
		{
			while (!r.EndOfStream)
			  sb.Append(r.ReadLine());
		}//end using

		String askResponseBody = sb.ToString();
		var monitorResult = jsSerializer.DeserializeObject(askResponseBody) as Dictionary<string, object>;
		String state = monitorResult.ContainsKey("state") ? monitorResult["state"].ToString() : null;
		if (String.Compare(state, "success", true) == 0)
		{
            //DOWNLOAD THE FILE
            //...
		}
    else if (String.Compare(state, "failure", true) == 0)
		{
			Console.WriteLine("Response Is FAILURE");
			Console.WriteLine(askResponseBody);
			count = MAXTRIES;
		}
		else
			Console.WriteLine(String.Format("Something went wrong. Response Is: {0}", askResponseBody));
	}//end using

    count++;
}//end while

If the service returns a “SUCCESS” message, then we just grab the package URL and download it. Otherwise, we write the return message out to the console so the build log will show the reason for the failure:

//get our Android package download url
//should be in form {"info": {"files": {"android": "ADDRESS"} ...
var info = monitorResult["info"] as Dictionary<string, object>;
var files = info["files"] as Dictionary<string, object>;
String dlURL = files["android"].ToString();
Console.WriteLine(String.Format("Download URL: {0}", dlURL));
Console.WriteLine("Downloading File...");

//download our file
HttpWebRequest dlReq = WebRequest.CreateHttp(dlURL);
dlReq.Timeout = 600000;
using (HttpWebResponse dlResp = (HttpWebResponse)dlReq.GetResponse())
{
	//stream to dl directory
	using (Stream r = dlResp.GetResponseStream())
	using (FileStream fs = new FileStream(String.Format(@"{0}\PockeTracker_{1}.apk", DLDIR, BUILDNUM), FileMode.Create))
	{
		byte[] buff = new byte[2048];
		int bytesRead = 0, totalBytesRead = 0;
		while ((bytesRead = r.Read(buff, 0, buff.Length)) > 0)
		{
			fs.Write(buff, 0, bytesRead);
			totalBytesRead += bytesRead;
		}//end while
		Console.WriteLine(String.Format("Downloaded {0} bytes", totalBytesRead));

		success = true;
		Console.WriteLine("Downloading Complete!");
	}//end using
}//end using

The downloaded package is then published internally for acceptance testing.’

Closing thoughts

Of course, there are many improvements we would like to make to the process. Automating our QUnit tests for the main application and JUnit tests for each Android native module will be our next priority. Another priority will be to add in support for our iOS native modules once those are completed. I hope that this example of our experience with the Trigger.io standalone build API will help you with your own build processes.

Sign-up for Trigger.io now to get started with your mobile app. Questions? Email support@trigger.io anytime.

Introducing OpenForge: an open-source cross-platform browser add-on framework

Trigger.io makes it simple for web developers to create native mobile apps for iOS and Android using JavaScript. But early on in our company’s history we also created a cross-platform browser add-on framework for Chrome, Firefox, Safari and Internet Explorer.

We are now open-sourcing that codebase, calling it OpenForge.

This codebase will be far from stale – development of the browser add-on framework will continue with a full-time maintainer who will also provide support. In open-sourcing the framework we have also provided the ability to build locally without reliance on Trigger.io infrastructure.

This will benefit customers that have already been building using our browser add-on tools, and make it possible for others to see, use and contribute to the codebase.

Codebase, docs and support

You can see the browser add-on platform code and tooling to build in this repo:
https://github.com/trigger-corp/browser-extensions

The README instructions give information on how to setup for local builds. The codebase is released under the BSD 3-part license which allows for unlimited commercial use. API docs are available here in Trigger.io’s legacy docs. In the future they may be hosted elsewhere but will be linked to from the README.

It is possible to get started using the framework for free, but as you get more serious you may want to get professional support to make sure your questions and issues are resolved, and any modifications you need are handled quickly. Antoine van Gelder at 7degrees is available to be contracted for this.

The history of OpenForge

OpenForge came out of the work that James Brady and I did with WebMynd where we built browser add-ons for search personalization that were downloaded more than 1.5M times.

We built a set of libraries for our own use to abstract away cross platform differences and realized that they could be useful to other developers. At the same time we saw the growth in Android and the problems that web developers faced in building for both that and iOS, and so Trigger.io was born.

The focus of Trigger.io has been on mobile platforms for a long time now, but at the start we also invested significantly in making our internal browser add-on libraries useful to others, and many of our team members contributed to that.

Initially our libraries were for Chrome, Firefox and Safari. Antoine van Gelder came on board and wrote the Internet Explorer SDK from scratch. At the same time in summer 2011 Connor Dunn and James Brady re-wrote much of the Chrome and Firefox code to tidy up and improve what we’d used ourselves to be ready for more public release. I then brought the Safari SDK up to speed.

Since then Tim Monks has improved the tooling, with Connor and especially Antoine continuing to update the SDKs.

What’s next?

With this announcement, Trigger.io’s browser add-on business is now completely separate from mobile. On the mobile side, with the Forge v2 platform release, we’ve been able to iterate native modules faster and faster.

You can expect more new modules, improvements to existing ones and our build tooling soon. As always we’re eager to hear from you either about OpenForge for browser add-ons or Forge for native iOS, Android and mobile web. Just contact support@trigger.io with your feedback or questions.

Trying your Trigger.io app on iOS 7

It seems iOS 7 will be released sometime in the next couple of weeks, so today, we're pleased to share with you a preview of how your Trigger.io app will look and feel on the new OS.

To run your app on iOS 7, you'll need a device with the latest beta build on it, or an OS X machine with the Xcode 5 preview installed.

Until iOS 7 and Xcode 5 are out of beta, you'll need to manually select the right platform and module versions for full iOS 7 support. What you need to do is:

  1. update your app to use Trigger.io platform version v2.0.1 (you can do this in the App configuration section of the Toolkit)
  2. if you're using any of these modules, update them to use version 2.1 (you can do this in the public modules configuration section of the Toolkit):
  3. iOS 7 requires some different icon and launch images sizes: see the configuration section for those modules for what's required
  4. restart your Toolkit to see 7.0 in the dropdown of available iOS simulator versions, if necessary
  5. if using the 7.0 simulator, you need to move Xcode 5 preview into the default Xcode install location, e.g. something like:
    • sudo mv /Applications/Xcode.app /Applications/Xcode.app-old
    • sudo ln -s /Applications/Xcode5-DP5.app /Applications/Xcode.app

There are a few other iOS-specific updates we'll make to our modules over the next few weeks (in particular, enabling you to customise the behaviour and appearance of the status bar). In the meantime, if you find any problems with the updated platform or modules, get in touch!