iOS PhoneGap – Splash screen control
Unfortunately a splash screen is still needed to hide the white flash that is visible just before the UIWebView loads its content. Previously before PhoneGap 1.0, you had no control over this – sometimes your content just takes an extra time to load and you want to control the duration of the splash screen.
There are two steps to enable this, firstly – in PhoneGap.plist, change the value for “AutoHideSplashScreen” to false (by default it is true for legacy code). This will not hide the splash screen, and it will remain on screen indefinitely.
Next, in your code, you will have to explicitly hide the splash screen.
After the deviceready event has been fired, you can call this function anytime you are ready:
navigator.splashscreen.hide();
If you want to just delay hiding the splash screen for 2 seconds for example, you can do this in your deviceready event handler:
setTimeout(function() {
navigator.splashscreen.hide();
}, 2000);
PhoneGap Xcode 4 Template (beta)
UPDATE: PhoneGap 0.9.5.1 includes the Xcode 4 template now, download it from phonegap.com
View the screencast below (best in full-screen, in HD).
Also, you can read the wiki article.
Xcode 4 template specs are undocumented and buggy. So, there are issues:
- We cannot automatically include the “www” folder in the template – the user has to add it in manually (a quick drag and drop). I added in checks and warnings if users try to run the app without adding this in.
- Some files, like .h and the -Info.plist file, are included in the ‘Copy Bundle Resources’ build phase by the template. No biggie during run-time, but for those with OCD they will want to remove these from the Build Phase (if only to get rid of the warning).
- Because Xcode 4 does not expand tildes (~), I cannot add a reference to the PhoneGap.framework in the user’s home folder, so I added it to a shared location /Users/Shared which has r+w permissions for everyone (the common folder /Library/Frameworks needs admin privileges). It was added here so users without admin privileges can still use PhoneGap.framework, and by extension, the Xcode 4 Template.
RELEASE NOTES
- beta1 – Initial release
- beta1.1 – Bug fix for issue #81 (moved framework from /Users/Shared/Library to /Users/Shared/PhoneGap)
- beta1.2 – Made /Users/Shared/PhoneGap writable to everyone
- beta1.3 – Fixed Template not copying over the ‘www’ directory from the framework location (happened only for users that only installed beta1.3 and didn’t migrate from an earlier beta version). This version was tested on a clean Mac OS X 10.7 Lion DP3 system running Xcode 4.1 DP5, and works great.
- beta2 – (UPCOMING) add AppleScript in the project Run Script build phase to get Xcode to automatically add the ‘www’ folder for you
Creating a PhoneGap project from the command line (for Xcode 4)
UPDATE: PhoneGap 0.9.5.1 includes the Xcode 4 template now, download it from phonegap.com
Currently the PhoneGap installer for iOS does not create an Xcode 4 template. The issue is tracked here.
I’ve created a shell script to create a PhoneGap project from the command line. You will still need PhoneGapLib installed – download the installer from http://phonegap.com and run it first.
Instructions are in the shell script itself (open it up in a text editor). View the script, then File -> Save As… to save it.
Cameron Perry has a good post about using PhoneGap with Xcode 4 that might solve some problems users might have.
UPDATE:
Nitobi is providing a web service to generate Xcode templates for PhoneGap-based projects.
Running your iPhone app in the Simulator without Xcode (with log support)
I started writing this shell script because Xcode 4 keeps crashing, so I ended up editing my code in TextMate, and had iTerm open so I can build, then deploy the app automatically in iPhone Simulator.
The script takes three arguments, the first is the name of the project (here the limitation is that it has to be the name of the .xcodeproj and the .app name), and the second is the configuration (Debug/Release – defaults to Debug), and the third is an optional argument, the name of the log file that the log will be written to (defaults to stderror.log).
Also, you will need the latest code of ios-sim. I could have added a step to check whether you have it installed and download, build and install it for you, but maybe next time
Make sure you download the latest source, and not one of the packages.
One you download it and build it, copy the ios-sim binary to somewhere in your path – /usr/bin is a good location.
Download the script. It is WTFPL licensed. Run it without arguments to see the help text.
Run chmod 755 sim-run.sh on the script to give it exec privileges.
The script builds your project, launches the project in the iPhone Simulator, activates the iPhone Simulator (brings it to front), logs the output to a file, and also displays the contents of the logfile as it is written to. On each run, it writes to a fresh log file, and the previous log file is backed up.
Xcode shell build phase, reporting of errors
Found this useful information, regarding Xcode error reporting for shell build phases. For example, if we were to include JSLint in PhoneGap iPhone, we could format the errors this way below so code where the errors occur are easily editable:
In shell build phases you can write to stderr using the following format:
<filename>:<linenumber>: error | warn | note : <message>\n
It’s the same format gcc uses to show errors. The filename:linenumber part can be omitted. Depending on the mode (error, warn, note), Xcode will show your message with a red or yellow badge.
If you include an absolute file path and a line number (if the error occurred in a file), double clicking the error in the build log lets Xcode open the file and jumps to the line, even if it is not part of the project. Very handy.
iOS Keychain Plugin for PhoneGap
So what is the Keychain? It’s a framework to store data (particularly passwords) securely on Mac OS X and iOS. You really don’t want to store passwords and other sensitive information in HTML5 local or web storage. This is a PhoneGap plugin for iOS that provides access to the Keychain through Javascript. Based on Buzz Andersen’s work – namely SFHFKeychainUtils
View the README and check out the sample app’s index.html for usage. Play around with the Get, Set, and Remove examples, should be self-explanatory.

PayPal Plugin for PhoneGap iPhone
First release of the PayPal Plugin for PhoneGap iPhone. Right now it handles static payments only (no dynamic changes to include shipping etc). Thanks to Chris Booth of Signature Digital in the UK for sponsoring development and also allowing it to be released to the PhoneGap community.
Nothing much to look at in the first screenshot, but with CSS styling and using PayPal’s official web button images it can look better. View the README and check out the sample app’s index.html for usage. Triggering the “Pay” button will launch the native workflow in the second screenshot.


PhoneGap iAds Plugin
Hey its a new plugin for PhoneGap. I call it the “PhoneGap AdPlugin”, and even though it only supports iAds currently, there is potential for supporting the other ad networks as a backup to iAds. Make sure you read the RELEASE NOTES in the README for limitations.
Get the source and view the README
Below are screenshots from the test app included, called ‘iAdHost’
PhoneGap Mobile Spec tests on iPhone
Fil who has been working on the Mobile Spec came over and we tested the mobile spec on the current (EDGE) version of iPhone PhoneGap, and the tests look pretty sweet (see video).
It was pretty easy, I created a new Phonegap-based Application from the Xcode template, plopped in the contents of the Mobile Spec, and just ran the app in the iPhone Simulator. In this session, we see that iPhone PhoneGap passes 51 out of 64 tests, for a 79% pass rate.
Contributing to iPhone PhoneGap – Part 1
[update: do not modify the core, instead create a plugin and add it into your app project. See PhoneGap Plugins for examples]
There has been a major re-factoring of the iPhone PhoneGap codebase, to better enable users to get a current version of PhoneGap to use in their projects without mucking about in the core PhoneGap code.
You can view the code here: http://github.com/phonegap/phonegap-iphone
The README has more details, and I will elaborate on it more here, especially on how contributors can add to the code.
PhoneGapLib/javascripts/core This is where you will add/modify your javascript code for PhoneGap core. You can add more javascript files here, but make sure you update the “PhoneGapLib/Makefile” file to include the newly added javascript file. For adding the file in the Makefile, the pattern should be obvious.
PhoneGapLib/Classes This is where you will add/modify your Objective-C code for PhoneGap core. You can add more Objective-C files here, but make sure you add it to the PhoneGapLib Xcode project also.
PhoneGapLib/javascripts/phonegap.js This is dynamically generated, and is generated whenever PhoneGapLib is built. You can update this file by running “make” in the PhoneGapLib folder, but generally it should be called in your application that includes PhoneGapLib (which the PhoneGap-based Application Xcode template does).
I will walk you through how to add a new command, by adding Application Preferences support. Download the files here.
Preferences.h
@interface Preferences : PhoneGapCommand {
}
- (void) boolForKey:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
// other functions here
@end
Note that the class inherits from PhoneGapCommand. The class name you use here is important, since you will be referring to it in javascript.
To ‘expose’ a function to javascript, it must have the signature from the example ‘boolForKey’ method above (first argument is a NSMutableArray, the second argument is a NSMutableDictionary).
Let’s now look at the javascript command to access the function above.
preferences.js
function PreferencesManager() {
}
var g_Preferences = new PreferencesManager();
PreferencesManager.sharedPreferences = function() {
return g_Preferences;
}
PreferencesManager.prototype.boolForKey = function(key, callback) {
PhoneGap .exec("Preferences.boolForKey", key, GetFunctionName(callback));
}
The important line is the “PhoneGap.exec” line. The first argument to PhoneGap.exec is in the form of [className].[methodName] (refer to Preferences.h to see the corresponding function which should be obvious). The next arguments to PhoneGap.exec are two strings, which will be passed into the “boolForKey” method in the NSMutableArray which is the first argument. If an object (json object) is passed in as an argument to PhoneGap.exec, that data will be passed into the “boolForKey” method in the NSMutableDictionary which is the second argument.
Preferences.m
- (void) boolForKey:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
NSUInteger argc = [arguments count];
if (argc > 2) { // no key and/or callback - just return, no point in continuing
return;
}
NSString* key = [arguments objectAtIndex:0];
NSString* callback = [arguments objectAtIndex:1];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL value = [userDefaults boolForKey:key];
NSString* retVal = value ? @"true" : @"false";
NSString* jsString = [[NSString alloc] initWithFormat:@"%@('%@', %@);", callback, key, retVal];
[webView stringByEvaluatingJavaScriptFromString:jsString];
[jsString release];
}
In the command itself, you can parse the arguments and options, and do whatever you need to do for your command. You can optionally write javascript back, using the method above, or the helper:
[super writeJavascript:@"alert('foo')"]
Don’t forget to add a Settings bundle file to your app as well.
Next: Adding your code to PhoneGapLib.

