Archive for programming

iOS Localization, some reflection and a hack

As an app developer, it can be quite effective to localize your apps (for this article, we focus on language), especially if you speak both English and your native tongue. At Japps, this is exactly what we do: localize at least to English and Dutch. Both iOS and Android provide means for this, although lozalizing the text on UI components is, frankly, a bit easier on Android. On iOS you are basically forced to duplicate your entire UI, which makes maintenance tricky (basically this violates the DRY principle).

Apple’s solution (prior to iOS 6)

Sadly, there are no real solutions available yet, although there are tools that speed up the process. The steps boil down to: duplicate Storyboard / nib files, extract strings from one language, translate strings into another and put them back (both using a command line tool). Any UI changes will require a repetition of these steps – however you can take a shortcut here by reusing most of the earlier translations. The great thing is that you can adjust your UI (sizes) to the different word lengths, but this is not always a big issue.

Alternative solution

Another solution that has been proposed is transferring the translation proces entirely to code by creating an outlet for each control that has text on it (see this tutorial). The downside is that that it requires quite some code for every new view. Furthermore, the texts in IB / storyboard will become totally meaningless, which may be confusing. To prevent this, they could be added just for clarity, but they’d still need to be defined in the strings file, which would again be non-DRY solution, and extra work.

Base Internationalization (iOS 6)

Luckily, Base Internationalization is coming, and it seems this will provide a KISS solution to localization on iOS. Auto layout could then ensure UI elements adapt their size and location to the length of the strings in the current language. This won’t work on iOS 5 though, so we’ll have to wait a bit before it is ‘acceptable’ to stop supporting the iOS 5 users.

Our solution (for the time being)

In the mean time, we crafted a bit of code that basically loops recursively over all views, checks the strings for square brackets. If anything is found like ‘[Blah]’ it is replaced by ‘BlahTranslated’, or ‘Blah’ if no translation was found. The latter means that for the ‘original’ language (ie the language that is used inside IB), no or only a few entries have to be added to Localizable.strings. For other (newly added) languages, everything can be added into one Localizable.strings file. Alongside, the UI in IB keeps being fairly understandable (since all texts are still relevant, albeit wrapped in square brackets).

This was implemented as ‘categories’ for NSString and UIView. In the latter case, subviews are checked recursively, and for different types of view (label, button, etc), slightly different steps are taken. The only thing that needs to be done is for every view that is loaded from IB  (in view controller’s viewDidLoad, or after manually loading the view from a nib) lngfkt.h needs to be included and [theTopView lngfk] needs to be called. In views that are instantiated from code NSLocalizedString can be used like ‘normal’.

The code

lngfkt.h

lngfkt.m

There’s a fair amount of edge cases that are not covered by this approach. Some just didn’t pop up yet (the above series of if statements could probably cover more UIView subclasses), others need some more trickery.

For navigation bars, the lngfk method has to be called separtely: [self.navigationController.navigationBar lngfk]. For static table headers and cell views, a bit of code is required in the class that implements the UITableViewDelegate class (the UITableViewController for instance):

The pitfalls

It is a hack. I doesn’t even really adhere to any naming conventions. We used it and found it a fair alternative compared to the other options. The code is posted just in case others like this idea as well. Please use it at your own risk. Also, this happens on runtime, which costs time. Not notably, in our case, but it could be.

 

iOS Core Plot (minimal example)

At our company, Japps, data plays an important role. We wanted to present graphs to the user inside our iOS apps. Luckily there is Core Plot (there’s other options, but we like this one). It works like a charm, it is extremely flexible, and it is open source (which is useful if you want even more flexibility or want to debug). There is also quite some reference code and Q&A available. However, I could not find a minimal example, so I created one.

Setting up shop

I created a new project from scratch, using the Single View template. I included Storyboard and ARC. Then I downloaded and installed Core Plot (I went for the static library approach).

In Storyboard, the class of the main view controller was changed to ‘CorePlotExampleViewController’, and this class was actually created (subclassing ViewController). The contents of this class is discussed next.

CorePlotExampleViewController.h

Now, CorePlotExampleViewController.h was slighty modified into:

What’s going on? Well, we import CorePlot-CocoaTouch.h, which gives us access to all Core Plot functionality. Also, we implement CPTPlotDataSource, why will become more clear later.

CorePlotExampleViewController.m

Next, we changed our view controller’s viewDidLoad:

What’s going on? First, CPTGraphHostingView* hostView is created. Alternatively you could (as described in other examples) do this via IB (Storyboard) and create an outlet and name it ‘hostView’.

Next, CPTGraph* graph is created and set as the hostViews ‘hosted graph’. Use the graph object to change axis and global layout. It can contain one or more plot spaces and actual plots (the lines, bars, dots, pies, etc). In this example, we take the graph’s default plot space and change its x and y ranges, this determines what part of the plot is shown to the user.

Finally, we create CPTScatterPlot* plot, the actual plot line itself. The X and Y values of the plot are not specified yet. Instead, we set its dataSource, that will provide the X and Y values upon the graphs’ request. To keep things simple, our CorePlotExampleViewController class will double as dataSource, but this could be a separate object.

To let our view controller double as datasource, we already let it implement the CPTPlotDataSource protocol (in the .h) file, and now only need to define two methods:

The method numberOfRecordsForPlot returns the number of plots. We simply set it to 9. The method numberForPlot is actually called twice (for an XYScatter plot at least, which is what we created) per data point (it took me a while to realize this). One time the X value should be returned, the other time the Y value. This is determined by fieldEnum.

The plot’s points are requested by their index, which in our case ranges from 0 to 8 (so 9 in total as we specified in numberOfRecordsForPlot). To get a nice quadratic plot without too much hassle we define x as ‘index – 4’ (but this could be something irregular as well, such as values returned from an array). The y value will then simply be x * x. The return value should be an NSNumber, so you’ll have to create this, for instance with numberFromInt, as in this case, or numberFromDouble (etc.).

Closing remarks

Well, that’s it really. You should now get a plot when you run your project. This is as simple as it gets, and from here you can make it as complicated as you want: change graph (theme, padding, border, background), change the axis (color, ticks, font, labels, location, multiple y axis), add more plots, change the plots line (thickness, color, symbols) add a legend (location, font), draw different plots (points, lines, bars, pies), etc. There’s is quite some information on this already, but perhaps I’ll do a followup post with the solutions we found for our graphing demands.

Why I think Android developers should rotate their phone often

In a well written app, when you rotate your phone, a lot happens on the background, but the user should not be aware of it. As a developer however, you should be aware, you should adapt to it, and you could use it in your advantage. Here’s why I think Android developers should rotate their phone often. Note: I’m linking to Stackoverflow questions here or there because the corresponding answers contain very practical and minimal code examples.

Adaptive layout

When a phone is rotated, the screen dimensions change. This may have a detrimental effect on the appearance of your app. It is very tempting as a developer to have only one testing device and adjust everything to that. Rotating your phone enables you to also get your landscape view good looking, and it also makes you aware of how important it is to expect the unexpected when it comes to screen size and resolutions, especially with Android, which runs on a wide range of devices (the HTC ChaCha for instance, has a screen that’s in landscape by default). You could decide you to ‘lock’ your screen to portrait. But when you’ve finished reading this blogpost, you might decide to do so only at the very last moment.

Activity restarting

When the phone rotates, the Android OS restarts the current activity. Something needs to be done to hide this event from the user! In a very simple app with views that have an id assigned, this will be done for you. But in many cases you will need to add code to make this work. Although you could catch the orientation event and prevent the restart of your activity altogether, the preferred method is to store the state of your activity in onSaveInstanceState. In the latter case, all important information about the current state of  your activity needs to be stored as key / value pairs (keys being strings). Stuff that does not fit the Bundle object used to be stored via onRetainNonConfigurationInstance, but this has been deprecated and fragments should be used instead.

Use it to your advantage

If you lock your app into portrait mode, you would not need to deal with the aforementioned issues. Well, at least not on rotation change. But your activity might be destroyed at any time. Especially when the user went away to do something else, but hopes to find your app in the same state as before when he / she gets back to it. This is one of the – in my opinion – nifty parts of Android’s ‘multi tasking’: stuff is kept in memory if possible, but destroyed and restored (in the original state, if the developer did his/her job) when needed in case of low memory. How to test for such events? That’s quite tricky, because it might take some effort to force the system to really destroy the activity. That’s when rotating your screen comes in handy: during this event, as far as saving and restoring instance state are concerned, the same happens as when your Activity gets destroyed.

Closing remarks

I’m currently using a Hackers News reader that actually did not implement the above. Every time I rotate my screen the app needs to reload stuff from the internet. When reviewing a developer, this is a simple way of testing whether he / she has at least some grasp of Android. If you care about your users and their experience, rotate your screen on a regular basis.

 

 

 

 

 

 

 

 

 

Hands on{x}

A Microsoft team from Israel released on{x} yesterday (as a beta version). This team researches location and activity awareness for Bing. On{x} enables the user to trigger tasks (reminders, website, sms) on events such as reaching a location, changing the way of movement (driving, walking, running) or simply on time.  For now, on{x} consists of an Android application with a website back end, connected by Facebook login. Let’s dive in.

Two layers of complexity

On{x} has basically two layers of complexity: ‘recipes’ enable non-technical users to quickly configure rules, while technical users can show their JavaScript skills. The interesting part is not yet up and running: having the latter group of users create ‘recipes’ that the first group can use.

Rules = Scripts

Basically, on{x} is a bunch of scripts, called ‘rules’ that can be turned on or off. Such a rule is simply JavaScript code that gets executed when the rule gets (re)loaded. JavaScript event handlers can be defined that are triggered when an event takes place somewhere in the future. An API (with documentation) is available for a range of triggers, and a range of actions. Scripts are written in the browser (Ajax.org Cloud9 Editor) and pushed to the phone upon save. There’s a logging system which is also accessible through the browser.

Play a song when reaching home

I decided to write a rule that starts playing a song when I get home. Pointless, but technically interesting. There’s a possibility to do this via geo-fencing: one defines an area after which triggers can be set to go off whenever the phone leaves or enters the defined area. This however requires GPS to be on, which is a potential energy-hog.

Trigger on Wifi

Instead I decide to try and detect if my home Wifi signal (SSID) gets into range. For this, the API is a bit vague but with help of the forums and some debugging I found:

This event is triggered when the phone does a Wifi scan. It is also possible to force a scan yourself:

The major deviation from the documentation here is that to get to the scanResults in JavaScript, toArray() has to be called. Basically, scanResults is a (wrapper around a) Java List object.

Play a song

Playing a song from the sdcard also was not very obvious. The good thing is that on{x} is only a very thin layer on top of Android and I finally found this to work:

Saving state

The last challenge was how to ‘remember’ that when we find the SSID of interest to be in range, it hasn’t been so before. For this, I used localStorage to store the state. State starts uninitialized. As soon as a scan has been conducted, state changes to ‘in-range’ or ‘out-of-range’. Only when switching from the latter to the first, the song will be played.

Closing thoughts

Before I paste my entire script (which I will submit for review by on{x}) below, first the final verdict on on{x}. Overall, it is a true beta: documentation is immature, the app kept crashing on me, logging has quite a lag, there’s very little ‘user friendly’ recipes at the moment, there’s a lot of ‘actions’ missing (changing volume, turning Wifi on / off) and finally the required Facebook login which seems to disappoint quite some users. However, there is already a lot of activity on the forums, and every webdeveloper who know his/her JavaScript can get started in no time. The recipe layer and the option for coders to publish their rules have a lot of potential as well.

At first it seems surprising Microsoft published this for Android. But in the end, this platform is the most flexible. The availability of an existing opensource JavaScript engine (Rhino) for Java may also have helped. Given the fact that on{x} is written so close to the Android architecture (WifiScan results, for instance, are android.net.wifi.ScanResult objects in a JavaScript jacket, device.applications.launchViewer is a very thin wrapper around Androids View intent, etc), I truly doubt if this will be available for other platforms any time soon, not without a lot of effort and abstraction of the API.

If a small startup had come up with this beta, they would have gotten my approval. But from Microsoft, I would have expected something more. They should have started with a closed beta: now the Play market is flooded with 1 and 2 star reviews, and they already used up most of the attention wave.

If you’re not a hacker, I’d stay away from on{x} for now. If you are, you might want to try it out, and hang around to see if this does becomes mature at some point and you can quickly jump in to seize whatever opportunity there may be.

Final script

As promised, the entire script on a platter:

 

 

 

 

 

 

 

PhoneGap templating with Mustache & jQuery

A useful habit to pick up somewhere along the road is templating. In this case, we will use the mustache.js templating engine, which can be used in a HTML & JavaScript setting. Templates consist of html containing {{variablename}} tags. The proposed solution (which uses jQuery) loads each templates from a separate file, which I find useful to keep things modular as well as orderly. Loading templates from separate files makes specifically sense in a PhoneGap setup, but works just as well in the browser, although in the latter case one often can reside to server-sided templating (or at least merge the separate template files into the main html file to prevent excessive http requests).

Note for testing: my Chrome browser threw some cross domain issues when testing this locally through the file:/// uri. For me (Ubuntu) the solution was to close Chrome and restart from the command line: google-chrome –new-window –allow-file-access-from-files file:///..

Templates

Let us start with a very simple file under tpl/test.tpl (relative to your index.html file) (create the tpl folder yourself).

Next, download mustache.j, throw it into your project and link it from your html file:

JavaScript – Loading the templates

Here’s a function you can use to load all your templates into (string) variables at once.

We load each file through an ajax request, and force jQuery to interpret the result as (plain) html. Note that we enforce synchronous loading: the script blocks until the template is loaded before continuing with the next template. This way we don’t have to worry about semi-loaded templates when the script continues.

This function could be called from jQuery’s document ready function:

JavaScript – Rendering a template

To render a mustache template, simply feed it with a structure that contains data fields that correspond to the {{fieldname}} tags in the template. These will then simply be replaced. The resulting html can be used to build your page, for instance with jQuery’s .html() command:

Wrap up and further ideas

From here on, you can make more, and more complex templates. You might also want to introduce better error handling / recovering. And when you have many templates, it may be an option to do partial loading or even loading on demand.