Extending PhoneGap to Return the iPhone’s Unique Identifier

22 Aug

Yesterday I wrote about the nascent project, PhoneGap, that acts as a Cocoa Touch-native wrapper to your web-based application.  I’ve been playing with it non-stop since I stumbled accross it and it works like a charm!

When phonegap initializes, it loads a few parameters from the client iPhone into your javascript environment.  By default these include the phone model, version, and gap version.  For my specific application, I wanted to load the iPhone’s unique identifier.

To add this uniqueIdentifier parameter is simple – looking in the phonegap sources, Find the GlassAppDelegate.m script in the Classes folder. Using Xcode’s method-finder bar, navigate to the (void)webViewDidStartLoad:(UIWebView *) method and replace it with the following:

- (void)webViewDidStartLoad:(UIWebView *)webViewLocal {
	NSLog(@"Page loaded");
	NSString *jsCallBack = nil;
	jsCallBack = [[NSString alloc] initWithFormat:@"\
				  __gap = true; \
				  __gap_version='0.1'; \
				  __gap_device_model='%s'; \
				  __gap_device_version='%s'; \
				  __gap_device_uniqueid='%s';",
				  [[[UIDevice currentDevice] model] UTF8String],
				  [[[UIDevice currentDevice] systemVersion] UTF8String],
				  [[[UIDevice currentDevice] uniqueIdentifier] UTF8String]
				  ];
	//NSLog(jsCallBack);
	[webViewLocal stringByEvaluatingJavaScriptFromString:jsCallBack];
	[jsCallBack release];

}

I’m simply access the uniqueIdentifier property of Cocoa’s UIDevice class.

To be able to access this paramter in your javascript, jump into the gap.js that you should be loading in your iphone web app, find the Device.init function, and replace with:

    init: function(model, version) {
        try {
            Device.available = __gap;
            Device.model = __gap_device_model;
            Device.version = __gap_device_version;
            Device.gapVersion = __gap_version;
			Device.uniqueIdentifier = __gap_device_uniqueid;
        } catch(e) {
            alert("GAP is not supported!")
        }
    },

Voila! You can now access the client iphone’s unique identifier via Device.uniqueIdentifier in your javascript.

Next up – figuring out how to access the keyboard through the UIWebView :X

  • any luck with getting access to the keyboard through uiwebview? I've been racking my brain trying to find a way. the only thing I could think of was to (for my specific example), create a stringByEvaluatingJavaScriptFromString message, where the javascript looks for a specific "id" on the page and then calls .focus() on it... I was hoping it would work, but no dice. it seems although it gains focus, that isn't enough to tell the iphone to pull up the keyboard :S
  • Hey Sahil - yes actually I did get the problem fixed. You can find my
    solution here:
    http://britg.com/2008/08/23/fixing-the-keyboard...

    Hope that helps!
  • Lieven Gekiere
    I tried implementing this again in the latest build ... but with no success. All other GAP functions do not react anymore ...

    Maybe you need to explain this to Sintaxi, so he can build it in in the next master.

    L.
  • Yes, I will definitely suggest adding this in to the trunk - not sure what
    problems you're running into as I didn't see those. If you can pastebin
    your code somewhere I will try to find some time to look at it in the next
    couple days.
  • Lieven Gekiere
    Here's the JS part


    *************
    var Device = {

    available: false,
    model: "",
    version: "",
    isIPhone: null,
    isIPod: null,

    init: function(model, version) {
    try {
    Device.available = __gap;
    Device.model = __gap_device_model;
    Device.version = __gap_device_version;
    Device.gapVersion = __gap_version;
    Device.uniqueIdentifier = __gap_device_uniqueid;
    } catch(e) {
    alert("GAP is not supported!")
    }
    },

    *************

    and in my page i have :

    *************
    window.onload = function()
    {
    Device.init();
    $('infomodel').innerHTML = Device.model;
    $('infoversion').innerHTML = Device.version;
    $('infouniqueid').innerHTML = Device.uniqueIdentifier;

    Device.Location.callback = updateLocationCallback;
    Device.Image.callback = 'image.lasso?data=';
    }
    ....

    *************
  • Hmm, that all looks solid. Here's a silly question - you've compiled and re-run the phonegap app in xcode, correct? also, are you using your physical iphone or the simulator?
  • Lieven Gekiere
    Could this be linked to the fact i'm using a 1st generation iPhone ? Is that not supported on them ?
  • From everything I've read I assumed that the ID is available to all iphones
    and ipod touches. I can't find a case in my limited searching where the
    first gen iphones done return a unique Identifier, but I don't have one
    myself.
  • Lieven Gekiere
    I get an "undefined" after adding all this to my project ... any idea's ?
  • Hmm, when and where are you getting undefined? i.e. what's the context? Are you doing something like alert(Device.uniqueIdentifier) ?

    If you can pastie your javascript code, maybe I can weed out the issue.
  • awesome... and thanks for figuring out the keyboard issue!
  • hey no problem!
blog comments powered by Disqus