API Development

Moving A Classic Titanium App to Alloy

Alloy Tech Tip

Last month, we explained some of the benefits of using Alloy instead of classic Titanium to build your apps. So, if you’ve got a classic Titanium app up and running and want to leverage all the great things Alloy has to offer, you might want to migrate your app to Alloy. And while this may seem like a complicated process to do, it really isn’t and can be done without significant code changes. All you need to do is move some files and some code to different files, and your app will work as expected.

Step 1: Move your files

So, a couple things need to be moved around. In a classic app, you’ve used the Resources folder. However, in an Alloy app, this directory should not be touched. In fact, this folder is generated by Alloy – so everything you put in this folder is overwritten automatically. The easiest thing to do at the start is move all of your current files to the app/lib folder. If this folder doesn’t currently exist, you can just create it.

What you have in your app.js file, you should move to controllers/index.js. In case you create any globals in app.js(which you should avoid as much as possible!), move those to alloy.js file instead.

The alloy.js file is meant for initialisation of your project. This file gets run before any other files. The second file getting touched on runtime is the index.js file – this is the first controller.

You should move assets to the app/assets folder. Images should go to app/assets/[platform]/images, fonts can go to app/assets/fonts. Image paths to these images are quite simple too. It is just /images/imagename.png – don’t need to provide the platform name at all.

Once you’ve done all this, you should be able to run your app as-is and all should work like you expect it.

Step 2: Migrating styles to controllers

Now that you’ve moved your files, you can slowly begin to make use of Alloy and its controllers. Keep in mind, you don’t have to do this. The migration process can be slow and can be done over future versions you’re going to produce.

Let’s say the first controller people see is a login screen, which is created in your lib/login.js file. Right now, you create all the UI elements using the Ti.UI.create structure. If you want to migrate this to Alloy, all you have to do is migrate all the create() and add() methods to Alloy.

So let’s say you have this:

var win = Ti.UI.createWindow({});
var username = Ti.UI.createTextfield({});
var password = Ti.UI.createTextField({});
var submit = Ti.UI.createButton({});
win.add(username);
win.add(password);
win.add(submit);
win.open();

 

In Alloy, you can transform the above classic code to the Alloy code below.

<Alloy>
 <Window id="win">
 <TextField id="username" />
 <TextField id="password" />
 <Button id="submit" />
 </Window>
</Alloy>

 

As you see, I preserved the variable names as the id of the elements. This is to preserve the naming. You don’t have to do this, but it makes it easier.

Let’s expand one of the createTextField properties. Previously, you had this:

var username = Ti.UI.createTextField({
    width: 200,
    height: 50,
    borderColor: "#999999",
    borderRadius: 5,
    borderWidth: 1,
    backgroundColor: "#eeeeee"
});

 

You can copy all the properties inside the createTextField method to your tss file. And again, use username as your naming.

'#username': {
    width: 200,
    height: 50,
    borderColor: "#999999",
    borderRadius: 5,
    borderWidth: 1,
    backgroundColor: "#eeeeee"
}

 

Because in the xml file you’ve already used username as the id of your element, you can refer to it using #username. All properties are copied over and now your textfield is fully styled.

Step 3: Migrating logic to controllers

Now that you have all the styling and views in your controllers, it is time for the logic. As per example above, it makes sense you’re listening for the click event on the button. So, let’s implement that.

Previously, you had this:

submit.addEventListener('click', submitLogin);
function submitLogin(e){
    // do login process here
}

 

You don’t want to do $.button.addEventListener right now as it can be a memory leak later on. Instead, you want to provide this in the xml like this:

<Button id="submit" onClick="submitLogin" />

 

You can keep your submitLogin function as-is. It will work automatically. And because you’ve added eventListenersinside the xml file, you also don’t have to clean them up, because Alloy will do that for you out-of-the-box.

Step 4: Using your newly created controller

Now that you’ve set up your controllers, you should start using them. And instead of doing require('login').getWindow().open() in index.js (or app.js in your classic application) you can now open them using:

Alloy.createController('login').getView().open();

 

And, if your first window after the login isn’t migrated to Alloy yet, don’t worry, you can still use your old way of requiring files and using classic in those files.

Conclusion

Now you know how to migrate your classic application to an Alloy application. Steps 2-4 are optional, but highly recommended. You can also migrate all your existing code as described in step 1 and then from there start creating new controllers.

One thing is for sure though, creating UI and its logic in the lib folder is not a recommended way of building apps. So don’t continue with that flow after you’ve migrated. The reason why it is recommended in this blogpost is for ease of migration.

Want to read more into how Alloy works? Look into the guides in the documentation.