PhoneGap 3.0 – Stuff You Should Know

September 5, 2013By 36 Comments

question-markPhoneGap 3.0 was announced recently and there are some important things to note that I have attempted to summarize below :).

PhoneGap CLI

If you hadn’t heard yet, the fastest and easiest way to use PhoneGap 3.0 is with the new Command Line Interface. To install the CLI, follow the specific instructions here.

This is a completely different approach than previous versions of PhoneGap where you would download a zip file of the latest version from here for instance (as listed under Archives). With this new CLI approach, once you run sudo npm install -g phonegap, you will have everything installed on your hard drive to start creating PhoneGap 3.0 projects.

So what does the CLI Create?

A lot happens behind the scenes when running the commands from the PhoneGap 3.0 CLI and understanding it will save time or possible frustration with project configuration. It’s actually really cool and easy and makes the whole development process much faster than prior versions of PhoneGap.

$ phonegap create ...

Outputs a sample application (www folder) with the following key components:

  1. config.xml sample for specifying application attributes for PhoneGap Build
  2. index.html (with included tags for phonegap.js script and CSS etc)
  3. index.css with basic CSS styles (css folder)
  4. index.js file with deviceReady handler (js folder)
TIP: When you create a new project, you should specify the name and project id using the long version of the create command, otherwise you will get a project named HelloWorld with an id of com.phonegap.hello-world. Fine for testing, but not what you’ll want for your real apps so I recommend getting used to the longer syntax off the bat. I personally like to explicity state the optional –id and –name arguments so I remember exactly what each parameter is doing. See the docs for more options.

$ phonegap create ~/Documents/PhoneGapProjects/PG30Testing --id "org.devgirl.pg30testing" --name "PG30Testing"

If you’re already familiar with the Cordova CLI, the PhoneGap CLI is actually built on top of it and provides the same functionality plus integration with PhoneGap Build. So with the PhoneGap CLI you can also build your application remotely from the command line without having to have all the native SDKs for each platform installed. See the paragraph titled Build Applications Remotely for more details.

Core Plugins must now be added… but it’s easy

WARNING: The newly created project will NOT include access to all of the API’s (aka features and plugins) documented in the PhoneGap API docs (geolocation, contacts etc) initially as it did in prior versions. Instead you install only those you intend to use via the CLI so your application’s performance is optimal and not bulky with code not being used. For instance, to install the geolocation plugin you would use the following command:

$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git

Where you’re specifying the phonegap local plugin add command, followed by the location of the project in git. The list of them all is here.

See the docs here as well for other core plugin locations.

Note that the plugin.xml does all the work for you in the new plugin architecture so you do not have to include the script tag in your index.html for that specific plugins’ .js file anymore, you simply add the plugin with the CLI and it’s ready to go. You also do not access it off the window object as before. So if you’ve added the Media plugin, you simply say var media = new Media(src) for instance. You can see the entry in the plugin.xml that refers to the Javascript source etc such as the following:

...
<js-module src="www/Media.js" name="Media">
        <clobbers target="window.Media" />
</js-module>
...

I recommend checking out the whole plugin.xml specification for more information. Also, my colleague Ray Camden did a post about using other plugins in 3.0 that can be found here.

Why all the www folders?

When you add a platform via the phonegap build, install or run commands, you will see another www folder created within each of the platform folders (ie: yourprojectroot/platforms/ios/www for iOS and yourprojectroot/platforms/android/assets/www for android). DO NOT use this folder directly as it is going to be overwritten every time those commands are run. You should always work from the root www folder and use the merges folder for changes specific to a platform. See Customize Each Platform in the docs for details on merges.

You may wonder why there isn’t a phonegap.js file in your root www folder. A different phonegap.js file is actually used per platform and copied into that platform-generated www folder at build and run time, but the included script tag was already put into your root index.html file for you.

Config files galore!

It might seem confusing to see the different config.xml files if you’re perusing through what’s created by the CLI commands. There is a sample config.xml in your root www folder that is used when a project is built remotely by PhoneGap Build (via the phonegap build remote command). However, when you are building locally for a platform you will make platform-specific changes to a config.xml file for each platform in a separate location. For instance, for android you will find it under a path like yourprojectroot/platforms/android/res/xml/config.xml. For ios you will find it under yourprojectroot/platforms/ios/yourprojectname/config.xml. This might lead to confusion if you’re not paying attention since you will also see the sample one in the platforms www folder which was copied down from the root project. The one in the platform-specific directory is the one to update and modify.

Note that you no longer have to add feature tag entries to your config.xml file for each plugin you add if they are installed with the above CLI approach and are 3.0-compliant. They will automatically be added into the platform-specific config.xml file at those platform-specific locations noted above.

Below are samples of the three config.xml files noted above to compare. I had added one Media plugin to my project before sharing this sample so you can see that one plugin specified as a feature…

PhoneGap Build Sample config.xml (in www folders)

<?xml version='1.0' encoding='utf-8'?>
<widget id="org.devgirl.pg30testing2" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
    <name>PG30Testing2</name>
    <description>
        Hello World sample application that responds to the deviceready event.
    </description>
    <author email="support@phonegap.com" href="http://phonegap.com">
        PhoneGap Team
    </author>
    <feature name="http://api.phonegap.com/1.0/device" />
    <preference name="permissions" value="none" />
    <preference name="orientation" value="default" />
    <preference name="target-device" value="universal" />
    <preference name="fullscreen" value="true" />
    <preference name="webviewbounce" value="true" />
    <preference name="prerendered-icon" value="true" />
    <preference name="stay-in-webview" value="false" />
    <preference name="ios-statusbarstyle" value="black-opaque" />
    <preference name="detect-data-types" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="show-splash-screen-spinner" value="true" />
    <preference name="auto-hide-splash-screen" value="true" />
    <preference name="disable-cursor" value="false" />
    <preference name="android-minSdkVersion" value="7" />
    <preference name="android-installLocation" value="auto" />
    <icon src="icon.png" />
    <icon gap:density="ldpi" gap:platform="android" src="res/icon/android/icon-36-ldpi.png" />
    <icon gap:density="mdpi" gap:platform="android" src="res/icon/android/icon-48-mdpi.png" />
    <icon gap:density="hdpi" gap:platform="android" src="res/icon/android/icon-72-hdpi.png" />
    <icon gap:density="xhdpi" gap:platform="android" src="res/icon/android/icon-96-xhdpi.png" />
    <icon gap:platform="blackberry" src="res/icon/blackberry/icon-80.png" />
    <icon gap:platform="blackberry" gap:state="hover" src="res/icon/blackberry/icon-80.png" />
    <icon gap:platform="ios" height="57" src="res/icon/ios/icon-57.png" width="57" />
    <icon gap:platform="ios" height="72" src="res/icon/ios/icon-72.png" width="72" />
    <icon gap:platform="ios" height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
    <icon gap:platform="ios" height="144" src="res/icon/ios/icon-72-2x.png" width="144" />
    <icon gap:platform="webos" src="res/icon/webos/icon-64.png" />
    <icon gap:platform="winphone" src="res/icon/windows-phone/icon-48.png" />
    <icon gap:platform="winphone" gap:role="background" src="res/icon/windows-phone/icon-173.png" />
    <gap:splash gap:density="ldpi" gap:platform="android" src="res/screen/android/screen-ldpi-portrait.png" />
    <gap:splash gap:density="mdpi" gap:platform="android" src="res/screen/android/screen-mdpi-portrait.png" />
    <gap:splash gap:density="hdpi" gap:platform="android" src="res/screen/android/screen-hdpi-portrait.png" />
    <gap:splash gap:density="xhdpi" gap:platform="android" src="res/screen/android/screen-xhdpi-portrait.png" />
    <gap:splash gap:platform="blackberry" src="res/screen/blackberry/screen-225.png" />
    <gap:splash gap:platform="ios" height="480" src="res/screen/ios/screen-iphone-portrait.png" width="320" />
    <gap:splash gap:platform="ios" height="960" src="res/screen/ios/screen-iphone-portrait-2x.png" width="640" />
    <gap:splash gap:platform="ios" height="1024" src="res/screen/ios/screen-ipad-portrait.png" width="768" />
    <gap:splash gap:platform="ios" height="768" src="res/screen/ios/screen-ipad-landscape.png" width="1024" />
    <gap:splash gap:platform="winphone" src="res/screen/windows-phone/screen-portrait.jpg" />
    <access origin="http://127.0.0.1*" />
</widget>

iOS-specific config.xml (under platforms/ios/YourProjectName/)

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.helloCordova" version="2.0.0" xmlns="http://www.w3.org/ns/widgets">
    <name>Hello Cordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <feature name="LocalStorage">
        <param name="ios-package" value="CDVLocalStorage" />
    </feature>
    <access origin="http://127.0.0.1*" />
    <preference name="KeyboardDisplayRequiresUserAction" value="true" />
    <preference name="SuppressesIncrementalRendering" value="false" />
    <preference name="UIWebViewBounce" value="true" />
    <preference name="TopActivityIndicator" value="gray" />
    <preference name="EnableLocation" value="false" />
    <preference name="EnableViewportScale" value="false" />
    <preference name="AutoHideSplashScreen" value="true" />
    <preference name="ShowSplashScreenSpinner" value="true" />
    <preference name="MediaPlaybackRequiresUserAction" value="false" />
    <preference name="AllowInlineMediaPlayback" value="false" />
    <preference name="OpenAllWhitelistURLsInWebView" value="false" />
    <preference name="BackupWebStorage" value="cloud" />
    <preference name="permissions" value="none" />
    <preference name="orientation" value="default" />
    <preference name="target-device" value="universal" />
    <preference name="fullscreen" value="true" />
    <preference name="webviewbounce" value="true" />
    <preference name="prerendered-icon" value="true" />
    <preference name="stay-in-webview" value="false" />
    <preference name="ios-statusbarstyle" value="black-opaque" />
    <preference name="detect-data-types" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="show-splash-screen-spinner" value="true" />
    <preference name="auto-hide-splash-screen" value="true" />
    <preference name="disable-cursor" value="false" />
    <preference name="android-minSdkVersion" value="7" />
    <preference name="android-installLocation" value="auto" />
    <feature name="Media">
        <param name="ios-package" value="CDVSound" />
    </feature>
</widget>

Android-specific config.xml (under platforms/android/res/xml)

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.helloCordova" version="2.0.0" xmlns="http://www.w3.org/ns/widgets">
    <name>Hello Cordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <feature name="App">
        <param name="android-package" value="org.apache.cordova.App" />
    </feature>
    <access origin="http://127.0.0.1*" />
    <preference name="useBrowserHistory" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="permissions" value="none" />
    <preference name="orientation" value="default" />
    <preference name="target-device" value="universal" />
    <preference name="fullscreen" value="true" />
    <preference name="webviewbounce" value="true" />
    <preference name="prerendered-icon" value="true" />
    <preference name="stay-in-webview" value="false" />
    <preference name="ios-statusbarstyle" value="black-opaque" />
    <preference name="detect-data-types" value="true" />
    <preference name="show-splash-screen-spinner" value="true" />
    <preference name="auto-hide-splash-screen" value="true" />
    <preference name="disable-cursor" value="false" />
    <preference name="android-minSdkVersion" value="7" />
    <preference name="android-installLocation" value="auto" />
    <feature name="Media">
        <param name="android-package" value="org.apache.cordova.media.AudioHandler" />
    </feature>
</widget>

One more thing… Java API Classes – Package Name Change

If you’re using any 3rd party plugins for Android and they haven’t yet been updated to the PhoneGap 3.0 spec then you will need to change the path to the following two classes within the Java plugin code for android:

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;

-to-

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;

More Info…

Filed in: CordovaHTML/JSMobile DevelopmentPhoneGap Tags:

About the Author ()

Comments (36)

Trackback URL | Comments RSS Feed

  1. David says:

    Very helpful as the current state of the phonegap docs aren’t quite there yet for using the CLI for 3.0.

    Having tried to install, build and deploy using the new phonegap cli for android and ios – it appears that being able to install directly to a device using a local build is not currently supported in the CLI version 3.0 for iOS but IS supported for Android (I can deploy to the iOS simulator fine using the CLI).

    Can anyone confirm that is the case?

    Thanks again for the helpful summary.

    • Hi David, yes, that is the current situation for iOS. From what I understand it will work with the upcoming PhoneGap 3.1 on iOS 7 devices. For now you’ll need to open the .xcodeproject that is generated from the CLI and run from XCode after you do the phonegap local build ios command… I will post if I find out any more info though… Thanks! Holly

  2. rowan says:

    Hey Holly, thanks for the summary.

    Are there any options to test PG 3.0 apps locally in a browser? It seems like Ripple only supports up to PG 2.6, and I can’t see any way to serve up the app locally (without an emulator). Am I missing something, or do I have to be running an emulator?

    Thanks!

  3. Dirk-Jan says:

    Thanks for your clarifying post!

    I’m still having trouble however, understanding the config.xml structure. If the root config.xml is only for remote builds, why are the entries still copied to the device-specific config.xml’s?

    In your example, the iOS-config.xml contains both ‘UIWebViewBounce’ as ‘webviewbounce’ (which is copied from the root config.xml). In my case ‘webviewbounce’ is set to False, but a build puts ‘UIWebViewBounce’ as True in the iOS config.xml.

    Am I supposed to put both the PG-Build compatible setting as well as the device-specific setting in the root config.xml?

    Any help would be greatly appreciated :-)

  4. Grumpy says:

    Hi,

    i use build.phonegap.com and there is says, zip the www folder and upload. Where do i put the different config.xml files?

  5. Mayur says:

    Hi Holly. Great post. Just tried Phonegap 3. Love it so far but when is it going to have Push Notifications plugin? Thanks. Mayur

  6. Anas Azeem says:

    So first, what do you do when you have to now return a boolean instead of PluginResult‘s object from the execute method. I mean, how to send data back to Javascript?

    Second, what should I do when the log says THREAD WARNING: exec() call to 'pluginName:methodName' blocked the main thread for 7949ms. Plugin should use CordovaInterface.getThreadPool().?

  7. Dan Kantor says:

    Thanks for the info Holly. One thing I’ve noticed – if I change the config file here yourprojectroot/platforms/ios/yourprojectname/config.xml then run $phonegap build ios, it overwrites this file and I lose my changes. Specifically, I’ve changed to “false” and it keeps getting set back to “true” after I build. Am I doing it wrong? Thanks!

  8. walid taraf says:

    Goodness me, that is sooo helpful, thank you. Tried to add a custom plugin with ‘cordova plugin add’ and error with plugman. Had to use the phonegap install instead. Pretty confusing when it comes to core plugins versus customized plugins. But that’s open source for you, we’ll make ends meet. Thx for your blogs.

  9. stefanie r. says:

    Hi Holly,
    First of all – great post but I have a question I added the Geolocation Plugin as you wrote in your post ($ phonegap local plugin add…). Now I have an error when i run my app – (uncaught exception: module cordova/plugin/geolocation not found) but when I look at the local plugin list (phonegap local plugin list) the org.apache.cordova.geolocation plugin is listed.
    Now I’d like to ask why this error occurs and what can I do against it?
    Thanks for answers.

  10. Holly,

    Thanks for writing this article. I’m only a few days into PhoneGap and it’s been a big help. I have one quick question…

    The “Why all the www folders?” section of this post indicates not to use the platform specific www folders, but that is where the .xcodeproj file gets created from the CLI create command. This causes XCode to make the “platforms/ios/” the top most directory shown in the project.

    How can I get XCode to show the true root level of the project instead of the ios specific folder? (Sorry if this is a stupid question….I’m new to PhoneGap and XCode!)

    Thanks,

    Joe

    • Johnnie L. Lindholt says:

      Hi :)

      I have the same question.
      Did you find a solution?
      You are not suppose to use iOS specifig files but that is where the xcode project file is located and it opens the iOS specifig files by default ???
      Also I ran the build command for iOS and it generated the iOS specifig files, but the updates I changes I make to the general files are not copied to the iOS specifig files even if I run build again???

    • juan says:

      You don’t need to change anything to Xcode. You do have a folder ‘www’ into platforms/ios this is what xcode uses to copile. However, when you run in the terminal ‘cordoba prepare’ the files from the root ‘www’ will be copied to the platform specific folder. So don’t worry, just make sure you run the ‘cordova prepare’ command. Hope this helps

      • Johnnie L. Lindholt says:

        Thanks for the response and sorry for the getting back so late.
        The command ‘cordova prepare’ is probably what I need to copy fils from root down into the os specific folders.
        Still I’m not sure how this can be used in a good process.
        When I work with phonegap I find the xcode project file and double click it. I then start developing my app.
        As I understand it I have now mad changes to the os specific files. I can then run the ‘cordova prepare’ command and I will get what ever is in the general folder copied down into to os specific folder, most lightly overwriting all my work.
        I love the idea of having a general folder that will be copied to all os subfolders, but are you not supposed to work in that general folder? And should the xcode project file not use that then?

  11. Varuna Singh says:

    Okay, by far the best, clean and up to date write up. This helped my clean my e-clogs a lot.
    Thanks!

  12. Minhaj says:

    In cordova 3.1 application navigator.notification.loadingStart() and Stop() are not working for me. Error comes is that ‘loadingStart is not method in NotificationEx plugin’. I am using old plugins LoadingView.h and,NotificationEx.h and m and UIColorExpand.h and m. Can u plz help me how to do this in cordova 3.1.
    Thanks in advance.

  13. SO HELPFUL. There’s so much conflicting information on older versions, etc. and the docs aren’t great. Exactly what I was looking for, thank you.

  14. Mike says:

    Holly has anyone mentioned an issue with iOS7 where the splash screen seems to bring the icon along with it? I have a splash loading with a giant stretched out icon behind it.

  15. Vessie says:

    All of your posts are great and very helpful. Clean and simple.I use them all the time. THANK YOU!

  16. Mateo Parra says:

    What if I’m NOT creating a new project, but updating mine.
    My current structure looks like this:

    index.html
    config.xml (only one)
    lib/
    js/
    css/

    I don’t know how I can update to phonegap 3.0 with the reamining folder structure, could anybody please help on this??

    • Mike says:

      Mateo I would build a new project, then grab index.html, js/, and css/ and add/replace what is created in root folder. From then on it will be a trial and error experience with CLI, Xcode, and for me Eclipse.

  17. Henco says:

    Thank you for the article!

    In phonegap 3.1.0 using Phonegap Build;

    I’ve tried to reference the Device plugin from index.html using;

    var src = ‘www/device.js’;
    // src is the plugin’s script relative to the plugin.xml file?
    var device = new device;

    Then trying to display some device information like;
    alert(device.model);

    Similar to what you explained above for the Media reference.

    But I cant get pass an error saying;
    “Type error: Undefined is not a function”

    Can you perhaps provide more info on referencing plugins from code?
    according to the docs one should just use

    var string = device.model;

    BUT that also gives an error:
    “Reference Error: device is not defined.”

    I’ve seen this error with other plugins as well.

  18. Roy M J says:

    I used to develop phonegap apps and recently spent time on other projects. Coming to use the new phonegap features and this article has been real helpful. I have a question though. I am using backbone.js to build the app. So when the app starts for the first time, it gives an error “Connection to the server was unsuccessful”. After some googling, i find suggestions that i have to minimize the js scripts and load them dynamically after device ready. Is this possible?

  19. Brian says:

    Ok so the section about all the www folders. I’m writing instructions for a class on how to use both Eclipse and Xcode to create projects. I used to have them directly modify the www folder that is now in ios/www, I want to be able to edit the html, javascript, css, etc files from the Xcode interface. It appears those files are linked to the ios/xcode folder and now the one in the root of the project folder or the merge folder. How should I allow editing from Xcode and still adhere to the don’t mess with the specific www folders for each build. It appears to me that this is a note only for using PhoneGap build, am I correct or am I missing something?

  20. jay says:

    Thanks Holly Schinsky

    This post is really helpful.

  21. Anjum says:

    Posting again after replacing xml brackets with ( )

    Thanks Holly,

    Great post. However I am still stuck with an issue. While working on Windows Machine I am using remote build of PhoneGap 3.1.0 and compiling for iOS remotely.

    I assume the platform specific config.xml is not applicable in this case for iOS as I am not building locally. I have tried the following changes one-by-one in the main config.xml file in www folder but have not been able to play the Audio in Background mode:

    ———-

    (gap:config-file gap:platform=”ios” parent=”UIBackgroundModes” overwrite=”false”)
    (array)
    (string)audio(/string)
    (/array)
    (/gap:config-file)

    ———-

    (config-file target=”*-Info.plist” parent=”UIBackgroundModes”)
    (array)
    (string)audio(/string)
    (/array)
    (/config-file)

    Can you please guide where should I put these lines so that they start impacting iOS build?

    Many Thanks & Regards

    Anjum

  22. Ravi Ada says:

    I am trying to upgrade our app from phonegap 2.7 to phonegap 3.3.3. Everything working fine but its crashing on iphone5s at getDeviceInfo method. Has anyone faced the same issue? any help is appreciated.

    Thanks
    Ravi Ada

  23. Deepan says:

    Can you explain , in config.xml

    xmlns: gap ? what about that widget parameter

    and how can i define features parameters for ripple Emulator

Leave a Reply