How to Convert a String Representing a Unicode Character Sequence to the Unicode Character

I recently received some translated resource files from the Translations team at work.  To my surprise, all of the files, even those for double-byte languages, were returned in ASCII encoded files.  After some inquiry, I found out that because of the technical limitations of a proven legacy system, all translation files were encoded as ASCII.  What this meant is that I was confronted with a set of ASCII text files containing Unicode escape sequences (\uxxxx) that I was responsible for converting to a proper Unicode encoding.

While solving the problem, I came across a couple solutions for converting Unicode escape sequences to a different encoding.  The first was to use the StringEscapeUtils class in Apache Commons Lang.

String lineOfUnicodeText = StringEscapeUtils.unescapeJava(lineOfASCIIText);

Using the StringEscapeUtils class is very straightforward; simply read the contents of the the ASCII file line-by-line, feed the line of data in to the unescapeJava method, and write the unescaped text to a properly-encoded new file.  But this technique requires writing a utility program to feed the contents of the ASCII files into the StringEscapeUtils methods and then write the transformed string to a new file.  Not hard to do, but much more work than ideal.

The second solution is to use the native2ascii utility included with the Java JDK.  The utility can take the input file and perform effectively the same unescape transformation that Apache Commons does.

native2ascii -encoding utf8 c:\source.txt c:\output.txt

A very simple solution that works as advertised.  No quirks or caveats that I’ve noticed.  There’s even an ANT task for incorporating native2ascii into build scripts.

Setting a Custom User Agent in Objective-C

Sadly, it is a common scenario in web development to have code that handles specific browsers, or classes of browsers, differently.  The practice largely has it’s roots in the “bad-old-days” of having to handle the many various quirks and idiosyncrasies in the different CSS and layout engines of the major browser vendors.  Thankfully, this problem is getting, largely, better (at least in my experience), and the need to write browser-specific code of this type is becoming less of an issue.

But handling layout differences across browsers isn’t the only reason to treat different clients uniquely.  Dropbox’s matching of the sort order paradigms of either Windows or Mac depending on which OS the site is being viewed on is a practical example of when functional differentiation is desired for different clients.

Dropbox on Mac

Dropbox on Mac

Dropbox on Windows

Dropbox on Windows

These techniques are nearly always implemented by inspecting the user agent string provided in the headers of each request the server receives.  Each browser provides a user agent header that describes the type, version, OS, and other relevant details about the client sending the request.  For a web application, the client application is the web browser, so you don’t need to worry about specifying one, the browser provides it. You only need to worry about consuming it if necessary.

But what about hybrid native applications where mobile content is running within a web browser control (such as UIWebView in iOS) within a native application.  By default, the web browser control typically sends a subset of the user agent string the full-browser version would send.  But what if you want your server code to recognize when your native application is submitting requests?  How can you specify details about the native application in the user agent string if you need the backend application to behave differently for these hybrid clients?

In the iOS SDK, the answer is to modify the UIWebView’s user agent string for your application.  This is easily done by:

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *existingUserAgent = [[[UIWebView alloc] init] stringByEvaluatingJavaScriptFromString:@”navigator.userAgent”];

NSString *newUserAgent = [NSString stringWithFormat:@”%@ custom-information-about-my-application”, existingUserAgent];
NSDictionary *userDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:newUserAgent, @”UserAgent”, nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaults];

/* … your application code … */

}

The essence of the above code is that the existing UIWebView user agent is retrieved from a UIWebView instance (it doesn’t need to be the instance that will actually display the content), the custom user agent information is appended to the original user agent, and then the new user agent is registered to the user defaults of the application under the key UserAgent.  This will set the user agent sent for all network requests sent from your application’s code, including raw NSConnection requests.*

In my experience, you should always augment the existing user agent rather than completely replace it as the server will likely make some assumptions about whether you are a supported client and what flavor of display code to deliver based on the web view control’s existing agent string.  This is especially true in large applications where you don’t own every aspect of the server code.

* NOTE:  Things can get a little weird for requests issued from a linked library (like making an API call such as stringWithContentsOfFile).  Therefore, it is dangerous to assume that EVERY server connection issued by your application will carry the custom user agent. Your milage may vary, so verify that the custom agent is being applied uniformly for all calls and adjust how the agent is registered if needed.

Fun with Simulators and VMs – Can’t Delete an Application from the iOS Simulator

For the most part, Apple’s simulator environment for iOS (both the iPad and iPhone), does a pretty good job.  There are mountains of odd “simulator-only” bugs and some obvious features are simply not implemented (three-finger+ gesture emulation anyone?).  However, as anyone who has worked with device emulators other than iOS’s can likely attest, Apple’s offering more than holds its own in terms of features and usability.

That said, the quirks and bugs can drive you mad.  The latest one I’ve noticed is that I am no longer able to uninstall an application from the simulator using the iOS “uninstall” feature (i.e. tap and hold the application’s icon until it starts to shake, then press the ‘X’ in the corner to remove the application).

This isn’t a big thing as re-running from the simulator will reliably (in my experience) replace the existing binary on the simulator.  However, there are times when I want to completely remove the application to remove things like the Settings bundle or resource and data files stored in the bundle directory of the application on the simulator.  The easiest way to do this had been to uninstall the application via iOS itself.

However, in the 6.0 or 6.1 SDK (I’m not sure when I first noticed, and I’m not motivated enough to track down the specific release the bug was introduced), the “uninstall” feature stopped working.  Tap and hold will still cause the icons to shake and the ‘X’ to appear, but pressing the ‘X’ causes the simulator to lock up.

The work around to this is simple.  You can just delete the application bundle directory from the simulator’s install directory on your hard drive.

Open the terminal and cd to:

cd “~/Library/Application Support/iPhone Simulator/6.1/Applications/”

Change the “6.1” in the above path to the version number of the simulator where the application you want to remove is installed.  If you issue an ls command in this directory, you’ll see a list of directories with GUIDs for names.  Each directory represents an application deployed to the simulator.  Find the directory for the application you want to remove and delete the directory

rm -r <GUID>

Nothing complicated, and for people comfortable with the terminal at least, an easy method for clearing a deployed application from the simulator.