Making mobile apps using Fuse

There's a new kid in town! In October 2015 the peoples over at Fuse announced their new UX tool suite for building awesome mobile applications as an open BETA. A tool meant to bring designers and developer closer together.

I tried it for the first time back in 2013, and a lot have changed since. With the much improved UX Markup and the integration of JavaScript you can easily get around creating great looking apps in no time. For the more advanced users, Fuse also let you access the native APIs directly using their own language called Uno, a native C# dialect. And if you are familiar with C#, nearly everything you know will apply to Uno code. While playing around with Fuse, I created a simple app displaying the bus departures time in Trondheim, Norway. You can grab the code on my GitHub page, and the project site.

There are of course other tools out there letting you create and deploy application on multiple platforms. But the cool thing about Fuse is its ability to push updates of the look and feel to multiple devices in real time. So for every bits of design and logic you change, Fuse will stream the changes to all connected devices while developing. Now the designers can flip pixels while the developer is writing the business logic, and all changes is reflected in real time in the application. No need to re-compile. You really have to try it!

Fuse

Native apps

Fuse code compiles down to native C++. So the code you write will run natively on each platform. Only Android and iOS is supported for the time being. This may change in the future.

Trying out Fuse

In order to start exploring Fuse all you need is to download and install the tool itself from fusetools.com. Their site is also the best reference for learning Fuse.

The Fuse team provides great tutorial videos for you to get started. Some bits are less documented in the documentation, but enough to get around, and you'll get an idea of what it's capable of doing. Fuse also has a growing community, and the whole team is actively answering questions you might have :-)

Creating our first app!

We will start out simple by using only UX Markup. UX Markup is a XML-based format that should be immediately familiar to anyone who has worked with similar formats. The root tag of your application is the <App> tag. This one bootstraps the app and takes care of the application lifecycle.

<App Theme="Basic" Background="#fff">
  <Text>This is header!</Text>
</App>

Reusable classes

The main .ux file might grow out of scale, and you might want to tighten it up by extracting some of the code, and make reusable components. This is achieved by declaring bits of the code as classes. They all can be contained inside the main .ux file like this:

<App>
  <Panel ux:Class="MyAwesomePanel">
    <Text FontSize="14">This is my awesome panel!</Text>
  </Panel>

  <!-- and use it here!-->
  <MyAwesomePanel />
  <MyAwesomePanel />
  <MyAwesomePanel />
  <MyAwesomePanel />
</App>

... or you can create a separate file like this:

<Panel ux:Class="MyAwesomePanel">
  <Text FontSize="14">This is my awesome panel!</Text>
</Panel>

And use it as the example above. No need for extra include statements.

Themes

Themes in fuse specifies how standard components will look and feel. The default theme is the Graphic theme that give the app an identical look and feel on all platforms. Alternatively you can use the Basic theme which is inspired by Googles material design. You can also specify Native theme if you want the app to have the native look and feel for the targeted platform. Be aware that the Native look and feel isn't supported on desktop. Which means you won't get any styles when previewing on desktop. If you want to use the preview on desktop, but still have the native theming on the devices, you can use the NativeWithFallback theme.

Themes are specified in the <App> tag:

<App Theme="Basic">

</App>

JavaScript

UX Markup itself can do magic, and other things like animations, triggers, interactions, and much more. But sometimes you need more. You need some kind of business logic. The app needs to do something. This is easily done by using JavaScript. The JavaScript itself will run through JavaScriptCore on iOS, and V8 on Android.

Here is an example on how you can write JavaScript for your Fuse app:

function click_handler() {
  debug_log('I just got clicked!');
}

module.exports = {
  click_handler: click_handler
}

And including it inside your .ux file:

<App>
  <JavaScript File="js/app.js" />
  <Button Clicked="{click_handler}" Text="Click me!" />
</App>

Multiple JavaScript files/modules

One thing you might wanna do is to split the JavaScript into different modules. Because, you simply don't want to write your whole app in one huge JavaScript file! Requiring other modules is easy:

<App>
  <JavaScript File="js/MyComponent.js" ux:Global="MyComponent" />
  <JavaScript File="js/app.js" />
</App>

js/MyComponent.js:

function MyComponent() {
  // .. do awesome stuff here!
}

module.exports = MyComponent;

js/app.js:

var MyComponent = require('MyComponent');

//...

Notice the use of ux:Global when including the JavaScript file in the .ux file. The file is still included without the ux:Global attribute. But to access it from other JavaScript code you need to give it a name.

Exposing native APIs with Uno

Uno is a native dialect of #C where you have direct access to Android and iOS APIs. I'll use the same example as they do in the documentation.

Let's start out creating a SystemSound.uno. This uno class will provide system notification functionality in the JavaScript. To do this we need to import the iOS and Android audio packages:

using Android.android.media;
using Android.android.app;
using iOS.AudioToolbox;

When creating a native module for JavaScript we have to manually define the members returned when it is used. Else it wont return anything. To do this we adds the members inside the constructor like this:

public SystemSounds()
{
  AddMember(new NativeFunction("playNotification",
      (NativeCallback) PlayNotification));
}

Now the calling JavaScript will get access to the playNotification function.

Next, we need to create the callback function PlayNotification. And since the Android and iOS API doesn't work the same way, we can't use the same code for both. It is therefore required to implement the functionality for each platform we want to support:

object PlayNotification(Context c, object[] args)
{
  if defined (Android)
  {
    var uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    var ringtone = RingtoneManager.getRingtone(Activity.GetAppActivity(), uri);
    ringtone.play();
  }
  else if defined (iOS)
  {
    Functions.AudioServicesPlaySystemSound(1310);
  }

  return null;
}

The PlayNotification function takes two arguments (Context c, object[] args). The first one is the running JavaScript context, and the second is the arguments that will be passed to the function by the JavaScript. This example doesn't need any of them. And we don't want to get anything in return either, so it will just return null.

The whole code would look something like this:

using Uno;
using Fuse.Scripting;
using Fuse.Reactive;

using Android.android.media;
using Android.android.app;
using iOS.AudioToolbox;

public class SystemSounds : NativeModule
{
  public SystemSounds()
  {
    AddMember(new NativeFunction("playNotification",
        (NativeCallback) PlayNotification));
  }

  object PlayNotification(Context c, object[] args)
  {
    if defined(Android)
    {
      var uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
      var ringtone = RingtoneManager.getRingtone(Activity.GetAppActivity(), uri);
      ringtone.play();
    }
    else if defined (iOS)
    {
      Functions.AudioServicesPlaySystemSound(1310);
    }

    return null;
  }
}

Let's use our new module!

Next up is to use our new module inside our application. This is done by calling it from the .ux file:

<App>
  <SystemSounds ux:Global="SystemSounds" />
  <JavaScript File="js/app.js" />

  <Button Clicked="{playSound}" Text="Play sound!" />
</App>

Which makes it avaiable as SystemSound to the JavaScript:

var SystemSounds = require('SystemSounds');

function playSound() {
  SystemSound.playNotification();
}

module.exports = {
  playSound: playSound
};

The Fuse team is rapidly implementing these kinds of abstractions inside the Fuse API. But you might come over native features that is not yet implemented. And by having access to the .uno code, you're free to make them yourself.

To sum it up

This was just a short introduction to what Fuse can do, and how you easily could get started on your new app project. It's super easy to set up, and very familiar if you've done some coding before. Especially if you have written code for the web. There are many more important things to learn about Fuse, like animations, interactions, triggers and more. And I couldn't cover it all in this post. However I believe that this quick read will help you get on track and the rest would be piece of cookies!

I've of course experienced some random crashes and bugs in the Fuse process at this early stage. Although this does not affect the application itself, it may be some kind of frustrating while writing it. But I'll say that it's wroth it. I really thinks this is a promising tool with great peoples working on it.

Head over to fusetools.com and check it out yourself. And make sure to check out the examples too!

Robohydra for your project

Robohydra? Pylons? Zealots?! Everytime I implement Robohydra in one of the teams projects, people tend to ask "did you just implement StarCraft again?!". And I have to admit, I've been using Robohydra a lot lately.

What is it? What is it good for?

First of all, Robohydra is "a web server designed to help you test any kind of HTTP client". So, what is it good for?

Let's say your team is told to fix and implement some JavaScript features on one of the biggie systems you've got. Maybe it is a huge social network with millions of users, or just your tiny webshop. The first thing you have to do is to set up the whole environment locally on your computer. Which means you need to sandbox the current system with the right database and software versions, and everything else.

Or you can just use Robohydra! With a simple Robohydra plugin you can bypass the hassle of setting up the system locally. All you need from the project is the few JavaScript files to solve the issue. How? You ask. Let me show you!

To get started, you need Robohydra:

var robohydra = require('robohydra');

// Get them HEADS
var RoboHydraHead = robohydra.heads.RoboHydraHead;
var RoboHydraHeadFilesystem = robohydra.heads.RoboHydraHeadFilesystem;
var RoboHydraHeadProxy = robohydra.heads.RoboHydraHeadProxy;
var RoboHydraHeadStatic = robohydra.heads.RoboHydraHeadStatic;

Then the proxy for our production site:

new RoboHydraHeadProxy({
  name: 'My Social Network',
  mountPath: '/',                   // application path
  proxyTo: 'http://example.com/'    // external application
});

And now the fun part! Say all your JavaScript files are located at http://example.com/js/. But locally it's in ~/awesomeProject/src/main/webapp/js/src. Here is where the magic happens. Robohydra lets you direct all request to a simple path on the external server to some local files. By using the RoboHydraHeadFilesystem you can simply serve static local files to all request towards http://example.com/js/:

new RoboHydraHeadFilesystem({
  name: 'My JavaScript files',
  mountPath: '/js',                       // external path to JS files
  documentRoot: 'src/main/webapp/js/src'  // local path to JS files
});

Now when you access the site through http://localhost:3000/ in your browser, all JavaScript files are served locally, while the rest is proxied from your production site.

Awesome!

But say you've already got the system set up locally. The problem now is that for every style you change, or JavaScript logic you add, you have to rebuild and redeploy the whole package. Maybe it's a Java package deployed on a local tomcat server. Well, you don't want to rebuild and redeploy the package for every change! Neither do you want to f**k up the Java code and configs some other developer has written to reflect your needs. Well, you can of course proxy local servers too. So simplyswitch the RoboHydraHeadProxy to point to your local server. And voilà. Same behaviour!

This is how the plugin will look like

var robohydra = require('robohydra');

var RoboHydraHeadFilesystem = robohydra.heads.RoboHydraHeadFilesystem;
var RoboHydraHeadProxy = robohydra.heads.RoboHydraHeadProxy;

exports.getBodyParts = function (conf) {
  return {
    heads: [
      new RoboHydraHeadFilesystem({
        name: 'My JavaScript files',
        mountPath: '/js',
        documentRoot: 'src/main/webapp/js/src'
      }),

      new RoboHydraHeadProxy({
        name: 'My Social Network',
        mountPath: '/',
        proxyTo: 'http://example.com/'
      })
    ]
  };
};

Some data not available outside the network?

Sometimes you may be told to demo a solution for peoples outside your company network. And you simply don't have access to the resources needed. What do you do?

The RoboHydraHeadStatic lets you serve static mocks without changing anything in your project. No extra configs, no adjustments, no refactoring. Your project is still untouched. The only thing you need to do is to construct som mock data, and run it all through Robohydra:

Mocks (data.json):

[
  {
    "name": "Super secret resource #1",
    "value": 10000
  },
  {
    "name": "Super secret resource #2",
    "value": 35000
  },

  ...
]

The plugin (plugin.js):

new RoboHydraHeadStatic({
  path: '/api/resource/:id',
  content: {
    success: true,
    results: res.send(data[id])
  }
});

Now when Robohydra runs alongside the rest of the system. All request towards /api/resource/(someResourceId) will return local mocks instead of errors caused by unavailable resources. And while we're talking about errors. You can of course return intended errors for the sake of tests too!

Here's another one. Let's say you need a resource that takes time to load. This is easily done by setting some setTimeout on the request handler, and of course, the RoboHydraHead allow you to do this:

new RoboHydraHead({
  path: '/slow/resource/:millis',
  handler: function (req, res) {
    setTimeout(function () {
      res.send({message: 'wooo!'});
    }, req.queryParams.millis || 10000);
  }
});

Sum it up already!

These are my main use cases with Robohydra. By using these methods you can simply create tests clients for your client-server application, return canned responses, static content, reverse proxy requests and a whole lot more. It also comes with a web interface that allow you to change its behaviour dynamically, with easy access to scenarios and test results. Head over to robohydra.org and grab your copy of this awesome tool!

Robohydra screen

Also. Follow the awesome creator, @estebanm and @robohydra, on Twitter.

Reading list

Mitt terminaloppsett

TL;DR Prezto med Paradox og SMYCK.

Min terminal

Så, etter å ha plagdes med rare slowdowns i oh-my-zsh ble jeg introdusert til Prezto - vistnok en optimalisert fork av OMZ som nå er blitt et eget prosjekt. Den føles mye raskere ut enn oh-my-zsh, og er i grunn bare awesome.

OPPSETTET MITT: