API Development

How to Make your App Future Proof

If you’ve been using Titanium for a while, you know it can sometimes be frustrating to have to make the app work again after a breaking change is implemented in a new major version. And, while this doesn’t happen very often, sometimes it does. Usually, this is a good thing, because it allows the Axway Appcelerator engineers to improve on existing functionality to improve performance. Other times, a breaking change is introduced to be able to have parity – offering the same functionality on both iOS and Android.

But still, even though a breaking change is there for a good reason, wouldn’t it be better if you could write your app in such a way that you’re ahead of the breaking change? I thought so too. That’s why I’m here to give you an insight into coming breaking changes for SDK 8.0 and 9.0.

Run on main thread

For a long time, you had a choice if you wanted to run the app on the main-thread or not. Starting in 8.0, your app will run on the main thread without the option to disable this. This shouldn’t impact your app a lot. However, you need to be more aware of the performance of your app, because heavy things can have impact on the performance. So, while any standard app isn’t impacted by this change, there are a couple things you can and should do right now.

Check if your app works just as well with run-on-main-thread property turned on. If you encounter any issues right now (which you shouldn’t as many people have used this feature for years), you can report a problem in JIRA before 8.0 releases, so you know your app works when that SDK comes out.

Having performance issues with “heavy” code in your app? There are a couple things you can do.

  • Load less stuff at once. For example, with tabgroups, only load the page visible at the start; in lists, render fewer items etc. A separate blogpost about this will come out in the near future.
  • Avoid image manipulation when you don’t have to. Image manipulation is quite heavy and should be done as little as possible. And, if you have to, make sure you store the results to be used at later times again.

For everything you do, consider when you should do it. Especially on startup, try to do as little as possible. There should be no need for many API calls, pre-loading views, many SQL queries etc.

If you do this correctly now, you will prevent any issues when you migrate to 8.0.0.GA when it comes out. For testing this, you don’t even need to update the SDK – you can just use whatever SDK you’re currently using. Although using the latest GA release is best of course!

iOS: JSCore

One of the things that has been announced for quite some time is the JSCore functionality. Right now, you can change whether or not you want JSCore to be used on iOS. Using JSCore basically means you want a JavaScript core to be bundled with your app instead of using the one provided by iOS itself.

Starting in 8.0.0.GA, this choice will no longer be available, and all apps will be compiled with the option ON. This means your app bundle will always be smaller, and the built-in JavaScript core of iOS will be used.

To make sure your app works just fine, if you have this property disabled, enable it now. You should see nothing really changes and nothing breaks, but in the unlikely event something does break, report this problem as a ticket in JIRA. That way you can be ahead of the change and make the Titanium SDK better even before the RC release of 8.0.0 SDK release.

Getters & setters

This has been a topic for a while already. What is the difference between properties and getters/setters? With getters/setters, I mean properties like view.getHeight(); and  view.setHeight(100), as opposed to just using view.height. The answer is, there isn’t a difference. And since using getters/setters isn’t really a standard JavaScript practice, they’re being deprecated. Starting in Titanium SDK 8.0, you’ll get warnings and in Titanium SDK 9.0 they’ll be removed.

So… which getters and setters are removed? This is an obvious question getting asked. Basically, all getters and setters that are pointing to properties that you can read/write to as well. So, the default things like heightwidthleft and top are some examples.

Getters/Setters that don’t reflect in a property are of course here to stay, like the setContentOffset of Ti.UI.ScrollView or setValue of Ti.UI.Silder. These setters give extra functionality you’d otherwise miss. A getter example would be getSelectedRow on Ti.UI.Picker – this one requires input and isn’t reflected with a property.

How do you prepare your app for this? Well, that is easy. Whereever you use a getter or setter that is exactly the same as the property (as most are), just refactor that to the property. You don’t have to do this for the entire app at once, since there is plenty of time before Titanium SDK 9.0 comes out. (8.0 isn’t even out yet!). Then, by the time 9.0 comes around and you want to switch, your code will be ready for it.

Change $.myView.setHeight(50) to $.myView.height = 50, and change var height = $.myView.getHeight() to var height = $.myView.height.

x & y coordinates

When positioning elements by default, you’re using dp. This means the iPhone 8 is 360 wide, as well as a lot of the popular Android devices.

However, when using 2dmatrix and touch events the positions weren’t (always) defined with this in mind, and you’d had to translate this manually by using the DisplayCaps object. Starting in Titanium SDK 8.0 this is no longer the case, as it will use the default configured in tiapp as it should have from the start.

So how do you prepare your code for this? Well that is a little bit more complicated as numbers will change from one SDK to the other. So, unlike our other examples you cannot prepare code for it in that perspective. However, you could check for SDK version using Ti.Version and match if it is version 8 or higher, at which case no more calculating is needed and you can just stick with the numbers that are coming through.

All you need is a simple if/else statement, and this won’t make you forget about it either. It’ll automatically switch over for you in case you forgot this change was going to be there, and whenever you really aren’t going to use an SDK lower than 8, you can just remove the if/else statement again.

blob.imageAs

Image blobs have a couple imageAs methods where you can manipulate the images. Some of these, all related to borders, will change slightly. Previously the behaviour was inconsistent cross platform, starting in Titanium SDK 8.0 this will change so that the borders will be added to the image instead of cropping out the existing image.

Affected methods are imageAsThumbnail, imageWithRoundedCorner and imageWithTransparentBorder.

As with the x & y coordinates, there isn’t really something you can do to prepare your code as the final result is actually different with the same methods. However, yet again I’d recommend adding a Ti.Version check right now already if you’re using these methods and rely on the image size on output.

Smaller changes

These changes are smaller, but might impact some of the apps. Have a look at this list, and then at your code to make sure you aren’t using anything. Some of these already trigger errors when you use them now, some don’t.

  • Ti.Yahoo is being removed
  • Some Ti.UI.KEYBOARD_* constants will be removed (triggers warnings already now, because they’re already deprecated).
  • iOS minimum deployment target is iOS 9. But since most of you target 9/10 or higher this shouldn’t impact too much. However, if you still target iOS 8 you should be aware of this.

Conclusion

Most breaking changes are easy to get ahead of. Some require a little bit of work but shouldn’t be to difficult. As with everything, if you encounter bugs in the SDK create a JIRA ticket. If you encounter other issues or have questions, jump onto the Slack community.