PhoneGap 2.1.0 in Mac OS X Mountain Lion 10.8: from Download to iOS App Store


These instructions follow the Getting Started with iOS guide at http://docs.phonegap.com/en/2.1.0/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS. (Earlier versions of this PG pointed to the wrong file.) PhoneGap uses “PhoneGap” and “Apache Cordova” terminology on its web site. I’m going to use “PG” often in this article for shorthand.

Before you can install the app on your device, you need to sign up as a Developer with Apple and go through the business documentation, Certificate Signing, and Developer Certificate process, all of which are detailed on Apple’s web site (https://developer.apple.com/programs/ios/), under Prepare for App Submission. Nevertheless, you can skip all those steps and still see your work in the the iOS Simulator included with Xcode. Xcode is a free download you can download now, but the Developer status comes at $99 a year. If you are new to creating apps for the App Store, you’ll want to peruse the App Store Review Guidelines to make sure your app falls within acceptable limits: https://developer.apple.com/appstore/resources/approval/guidelines.html

Xcode Install and/or Upgrade 

1. This install requires Xcode 4.3 or later, and Mac OS X Lion 10.7 or later, both available from the Mac App Store (http://www.apple.com/osx/apps/app-store.html). Install those now if you don’t already have them.
2. I already had Xcode installed. With the September 2012 release of iOS 6 on the new iPhone (with the longer 4″ screen – this article was written late Sept. 2012), a new version of Xcode was available. I upgraded Xcode to 4.5, which included support for iOS 6. You must use Xcode 4.5 in order to code for iOS 6 on iPhone 5. (Note to self: I use an iPod touch for a development device. As per an Apple Developers Forum reply about iPod touches, only the 4th and 5th generation iPod touches support iOS 6.)
3. This PhoneGap install requires the Xcode Command Line tools, so I opened Xcode to download it – Xcode Preferences > Downloads > Components > Command Line Tools > Install (115.4MB). Downloading this package will install copies of the core command line tools and system headers into system folders, including the LLVM compiler, linker, and build tools.

Download Apache Cordova 

1. I downloaded PG 2.1.0 from http://www.phonegap.com/download (22.2MB). The zip file was unzipped and downloaded to

Downloads/phonegap-phonegap-26d211b/

2. Initially, I had no idea where to go next to get the install working. I looked in lib/ios/bin and saw no dmg file. Actually, PG now uses Terminal to set up PhoneGap. I’m normally an icon-pushing guy, so I was pleasantly surprised how well the command-line interface worked to set up the project with Terminal. I had a few false starts, because I included a $ in front of my terminal text input because it was shown in the getting started guide. As you’ll see in Terminal, your waiting message already ends in a $, so you don’t need to type that in. Here are the install instructions using Terminal, which you follow when you want to create a new project.

Create a New Xcode Project 

1. Open Terminal by tapping on the magnifying glass in the upper right corner of your monitor and typing Terminal in the Spotlight box. Click on the Top Hit, Terminal. A Terminal app window opens.
2. In Terminal, I changed directories to start at my Downloads folder by typing:

cd Downloads

3. Determine where you’ll store your new project files and write down the path, starting with /Users.
4. In Terminal, you’ll make the path to the ios/bin/create file inside the PG folder you just downloaded, then to the new project’s location, then the reverse-domain-style package name, then the project name, no spaces, like this:

./phonegap-phonegap-26d211b/lib/ios/bin/create /Users/[myname]/Documents/NewProject com.stevehusting.projectname projectname

5. Wait until the cursor returns, then exit the Terminal.
6. If you look inside Documents/NewProject, you’ll find it filled with folders and files. A www file has been created for you, complete with the cordova-2.1.0.js file and startup index.html page (the page you’ll see when opening your app in the device or emulator). In the past, PhoneGap startup Javascripts were put at the head of the index.html file; now they’re stored separately in js/index.js as an external file. If you’ve used PG in the past, I think you’ll agree this was a very smooth install! They’ve done a very good job with this version.
7. Double-click on projectname.xcodeproj to open it in Xcode.
8. Click on the gray arrow for the blue icon for project name in the upper left corner of the Xcode environment. Now you see the folders for the project appear.
9. Click on the index.html file. The contents appear in the middle pane of the Xcode environment.
10. As a test I’ll explain later, add the following line directly under the <h1>Apache Cordova</h1> line:

<p><a href=”http://www.phonegap.com/”>Click Me</a></p>

11. Hit File > Save to save the page.
12. In the upper-left of the Xcode window, you’ll see “Run,” “Stop,” and “Scheme.” Above Scheme I see “projectname > iPad 6.0 Simulator.” You can click on on iPad 6.0 Simulator to change it to iPhone if you wish. (When you archive — create your binary — for the app store, you’ll change it again to “iOS Device.”) Go ahead and click on the button above Run.
13. You’ll see a Build Succeeded box, the iOS Simulator load, then the index.html file in an simulated iPad 6 showing the Apache Cordova logo and “Device is Ready” pulsing below. Pretty cool!
14. Click on the link. You’ll find that the link is broken. In Xcode, look below the index.html file contents to the log window. It’ll tell you why the link did not work:

ERROR whitelist rejection: url=’http://www.phonegap.com/&#8217;

We will be fixing this in the next section.
15. In Xcode, click on the Stop button, then on the gray folder button below the Run button to see the files again.
16. Tap on the simulator and exit the Simulator.

Setting Up the Project in Xcode 

1. To take care of the whitelist error, add your allowed hosts in Resources > Cordova.plist under ExternalHosts (such as http://www.phonegap.com). To do this step, click on Resources > Cordova.plist, then on the gray triangle to the left of ExternalHosts, then on the + sign and type the text in the far right field. Typing in an * will allow all external URLs to work. Then tap outside the field and save the changes by File/Save. (To understand all the other settings on that file, visit here: https://github.com/apache/incubator-cordova-ios/blob/master/guides/Cordova%20Settings%20File.md).
2. Click on Run and try the link again. It should take you to the PhoneGap.com web site. However, the web page opened in a new screen, and there was no way to get back to the app from there. We would need to turn off the device and turn it on again to get the app to open again. So we need to install the ChildBrowser plugin to rectify this (I amy write an update on this install later. Perhaps the article I wrote earlier for Childbrowser installation will still work. I have not checked).
3. Drag or copy all the HTML, CSS, and JS contents of your project into the “www” folder in the Finder window, NOT into Xcode.
4. Run Product > Clean, then Run Xcode in the simulator to test. Test the external URLs and check for any whitelist errors, and fix, if you decided not to use *.

Check the Properties List 

1. Click on the Resources folder in Xcode’s left pane and click on projectname-info.plist and make sure the Bundle Identifier line is correctly populated with the reverse-domain-name you included in the Terminal.
2. Still in projectname-info.plist, change the Bundle Display Name to the name you want under the icon on the home screen. Keep it short and remember to test it later in your device. Titles of 11 or fewer characters work best. Titles too long will truncate and end with ellipses (. . .), which look poor!
3. In YourProjectName.plist, hold down the cursor over an entry in the Key column until the + and – buttons appear, and click on the + button to add a property. Choose the “Icon already includes gloss effects”, and “YES” if you don’t want Xcode to add the gloss effect to the app icon that will appear on the device’s home screen. Select “NO” (default) if you want Apple to add the gloss to top of icon.
4. Before leaving this page, save.

Set Up the Build Settings

1. At the top of the left folder pane, click on the blue heading showing your project name. You see three panes in the Xcode environment. In the middle pane under TARGETS, click on the project name. Under the Summary tab, make changes where necessary, such as Version number (1.0), Devices supported (iPhone, iPad, or both – Universal), and Deployment target. It’s important to select a deployment target that your code supports AND (for testing purposes) the earliest one your test device includes. I chose 4.3, which is believe is the minimum this version of PG supports. Also click on the Supported Device Orientations you want your device to support. Don’t worry about the Main Interface. Lastly, if you have supplied the icons for the project, they should appear in the App Icons section (scroll down to see). If one is missing, you’ll see that, too. More about icons later.
2. Under Build Settings tab, Architectures heading, select your Base SDK to reflect the latest iOS installed on your computer. In my case (as of Sept. 2012), it’s iOS 6.0.
3. Under Build Settings tab, Code Signing heading, Debug setting, make sure the iPhone Developer setting is current if you want to test in your device. For the Release setting, choose the Distribution profile. These would have been created online, downloaded, and installed previously. You can save this step for later, when you are ready to upload to Apple.
4. Under Build Settings tab, Deployment heading, select the iOS Deployment Target your code will support, AND if you can test it on a device containing that version. It should be the same as step 2.

5. Under PROJECT, click on the project name (above the TARGETS name). You will repeat the above steps with the same settings. Many errors arise from entering the information only once – the information has to be entered twice.
6. Under Build Settings tab, Architectures heading, select your Base SDK to reflect the latest iOS installed on your computer.
7. Under Build Settings tab, Code Signing heading, Debug setting, make sure the iPhone Developer setting matches your project name if you want to test in your device. Choose your Distributor profile for the Release setting if you have one already.
8. Under Build Settings tab, Deployment heading, select the same iOS Deployment Target.

Fixing Warnings

Xcode, after every launch in the Simulator, shows us any warnings or errors it generates in the left column. Warnings have a yellow triangle associated with them; errors are symbolized by a red circle and a failed build. The file containing the warnings is listed as well as the specific warning for that file. A file may contain more than one warning. This project generated a few warnings. Let’s tackle them now.

Fixing Warnings: “missing Default-568h@2x.png”

1. iOS 6 in iPhone 5 with the Retina 4-inch display requires a different splash screen (launch screen) image size. When you click on the warning, Xcode will ask if you want it to supply the image for you. If you answer yes, the warning will go away, and you’ll have a black starting image. You’ll see it listed right above the blue www folder in Xcode if you click on the gray folder icon under Run at top left.
2. If that’s not what you want, simply prepare your own image and upload according to the instructions coming up.

Fixing Warnings: MainViewController.m, AppDelegate.m “invokestring” is deprecated

1. After my build, I got the following warning three times:
“invokestring” is deprecated
2. 1. Open Classes > MainViewController.m and comment out this section by adding /* before and */ after as shown:

/*
#pragma UIWebDelegate implementation

– (void) webViewDidFinishLoad:(UIWebView*) theWebView
{
// only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle
if (self.invokeString)
{
// this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready
NSLog(@”DEPRECATED: window.invokeString – use the window.handleOpenURL(url) function instead, which is always called when the app is launched through a custom scheme url.”);
NSString* jsString = [NSString stringWithFormat:@”var invokeString = \”%@\”;”, self.invokeString];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}

// Black base color for background matches the native apps
theWebView.backgroundColor = [UIColor blackColor];

return [super webViewDidFinishLoad:theWebView];
}
*/

Save the file.

2. Also open Classes > AppDelegate.m and comment out the following line by adding two slashes to the left, like this:
// self.viewController.invokeString = invokeString;

Save the file.
4. All three invokestring warnings should now be gone.

Set Up Your Icon and Splash Images 

1. Still in Xcode 4, click on the Resources folder at left. Replace the splash and icon images with your own. Right-click on the folder and select to “Add files to ‘project name…’”, and navigate to the files for insertion.

If you haven’t made the icon and splash screen files, here are the required pixel sizes of each (from Apple’s iOS HIG – Human Interface Guidelines):

Images preferred are PNG, 24 bits depth.

App Icons, iPhone:
icon.png = 57 x 57px
icon@2x.png = 114 x 114px

App Icons, iPad:
icon-72.png = 72 x 72px
icon-144.png = 144 x 144px

splash or launch images:
Default.png = 320 x 480px
Default@2x.png = 640 x 960px (Retina 3.5 inch)
Default-568h@2x.png = 640 x 1136px (Retina 4-inch). For simple apps like mine, just adding this to my project will automatically adjust the height of all my pages – no other coding will be needed to eliminate the black bars above and below.

iPad splash or launch images:
Default-Portrait.png = 768 x 1004px (corrected)
Default-Landscape.png = 1024 x 748px (corrected)
Default-Portrait@2x.png= 1536 x 2008px
Default-Landscape@2x.png= 2048 x 1496px

You’ll need to add the above icons to your Xcode project internally. The following images are uploaded to the App Store separately:

App Store icons (JPG or PNG):
1024×1024 (iPad)
512 x 512 (iPhone)

Newsstand apps, later iPhone and iPad:
At least 1024 pixels on the longest edge

Newsstand apps, earlier iPhone and iPad:
At least 512 pixels on the longest edge.

Screenshots (JPG or PNG):

You can get the screenshots by hooking up your device, then going to Window > Organizer > Devices, then under Library choose Screenshots. Go to the screen you want to grab in your device, hold down both buttons momentarily to take the screengrab, then it should appear in Organizer (I’m recalling this from memory). Yo can then click on the selected screenshot and then on Export to save it to a folder. A button allows you to Save as Launch Image too!

On a hunch, I opened Grab, and got a screengrab of the iOS screen in the iOS Simulator. Upon trimming it down, it was a TIFF image of only 318 x 454px size. I would need to open a graphic program to save as PNG and size it up to 320 x 480.

An alternative that works for me is to open your app in a browser, size it by eye, then do a screen grab. If the grab dimensions were too small, then enlarge the view (control +) and try again. Then in your graphics program, open a window of the correct size and place the image there, sizing the width to fit and letting the bottom slide out below.

Screenshots should not include the mobile status bar along the top. Here are the requirements for upload to the App Store.

The requirements for high-resolution screenshot images are 960 x 640, 960 x 600, 640 x 960, or 640 x 920 pixels. Images must be at least 72 dpi, in the RGB color space, and the file must be .jpeg, .jpg, .tif, .tiff, or .png. You can update your screenshot files at any time in iTunes Connect.

In addition, the iPhone 5 has a new screen size. New and revised apps must submit the following sizes:
portrait: 640 x 1136px or 640 x 1096px
landscape: 1136 x 640px or 1136 x 600px

Build for the App Store!

Assuming you’ve got your Developer’s certificates and profiles in working order, and your app is working fine in your test device, it’s time to put it on the App Store. If you are getting code signing errors, head over to here to debug them: http://developer.apple.com/library/ios/#technotes/tn2250/_index.html

1. If everything is working fine, then do a File > Create Snapshot of your current working project before the next steps so you can revert if necessary. A Snapshot is a copy of the project stored away. You can delete these snapshots by going to Window > Organizer, click on Projects at top, then on the project name at left. After clicking on a Snapshot, click on the Delete Snapshot icon at lower right. This will free up a lot of memory after you’re sure you will no longer need the earlier versions. If you need to revert to an earlier version (snapshot) of the project, you will first create a new folder in Finder, then click on the Restore Snapshot icon to save it to that folder. You’ll have two versions of the project; this way the reverted version will not overwrite the previous version.
2. Fill out the Application Assets Template located here: http://wp.me/pyIb9-1o
3. You’ll need to go online to the Apple Developer site, sign in, and click on the iTunes Connect link.
4. Click on Manage Your Applications and either Add New App, or choose an existing app to upgrade. Follow the steps online and transfer all the information into the fields from the Application Assets Template you just filled out.
5. You need to finish to the point you see a button saying that it is “waiting for binary.” With that status, you are ready to upload a binary. Let’s do that next.

Upload a Binary

1. A binary of the app is the compiled version of the app that is made up of 0s and 1s. To compile your app for the App Store, make sure your device is unconnected and the Scheme in Xcode shows “iOS Device.”
2. Do a Product > Clean while holding down the option key. Then do a Product > Archive and wait for the app to build.
3. The Organizer window should open. Click on Distribute. If all went well, then follow the steps until the app has been successfully validated and uploaded to the App Store.
4. While you wait until you get an email saying the app is “Ready for Sale,” you can go back to the Developer’s site and click on the link for App Store Approval Process (found in the same right menu below the iTunes Connect link). Along the way, you’ll get status notifications in your iPhone or iPod touch giving you the status of your app as it goes through the approval process.

52 thoughts on “PhoneGap 2.1.0 in Mac OS X Mountain Lion 10.8: from Download to iOS App Store

  1. Nice tutorial.

    It started off making good sense, however, my lack of terminal understanding left me quite confused.

    Why would have phonegap opted for a terminal install?

  2. Unless I’m reading it wrong, your section “Download and Install Apache Cordova” doesn’t actually tell me how to “Install Apache Cordova.” I assume I’m missing something, but have no idea what. If I just create the xcode project the project says “Base SDK Missing.” I feel as though you may have left out a crucial piece of instruction here.

    The actual phonegap documentation is pretty terrible (and has only been getting worse since 1.5) , so thank you for putting something like this together.

  3. The use of the PG download is in the very next section, in which you use Terminal to set up the Xcode files with the PG download. I went ahead and removed “and Install” from the title. It was a bit misleading!

  4. Thanks for this! The instructions and documentation on their site and in their “How to Install” files in their download package are horribly fragmented. I at least was able to create a Hello World project. For some reason, I was not able to get that link working to http://www.phonegap.com. Even after I added, the * to the External Hosts.

    I’ve been a Phonegap user since about 1.2 and this time is probably the worst, most painful upgrade. I know it’s not all their fault because of the way Apple works (closed source basically).

    Do you have issues i.e. ‘invokestring’ is deprecated?

    • I am not a sophisticated developer by any means. I know very little Javascript or Objective-C. I’ve spent two years on a website using PHP/MySQL. So all my apps are relatively modest when it comes to complexity – zero or one plugins, for example. Any issues I have on deprecation are on the Xcode side, and occur in the code create by a designer I had hired way back when to build it in Obj-C. Luckily, I know enough of Obj-C basics to look up the docs to find the replacement for a deprecated wrod (or contact the original coder). But invokestring is unfamiliar to me.

  5. Thanks for this tutorial. After step 12 in Create a New Xcode Project, I get ‘Cordova/CDVViewController.h’ file not found after running the app. Any tips are appreciated.

    • If you look in the upper left, you’ll see a long text box with the word Scheme below it. Click on the word Cordova in the box. Then click through until the word “game” appears there. You are building for Cordova rather than your app. Are you sure you downloaded 2.1.0?

  6. one more thing, you may wanna put below after ondeviceready for iPhone 5.0

    if (window.screen.height === 568) { // iPhone 4″

    document.querySelector(“meta[name=viewport]”).content=”width=320.1″;

    }

  7. 2 more things is that iOS 6 always try to cache your GET or POST request. Hence, you need to add below if you are using jqm 1.1.1 and phonegap 2.0 and above:

    // below is needed for iOS 6.0 where it caches every POST request
    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    // you can use originalOptions.type || options.type to restrict specific type of requests
    options.data = jQuery.param($.extend(originalOptions.data||{}, {
    timeStamp: new Date().getTime()
    }));
    });

    and these shouwld comes after jquery-1.7.2.min.js script

  8. Pingback: Installing the SLQite Plugin into Cordova 2.1.0 in iOS | iPhone Dev Log

    • I carefully say “in Xcode” or “in Terminal” and even mention certain pages the code belongs in. If you are still having trouble, please point out where I’ve missed a location.

  9. hey thank you SO MUCH for the great article – very much appreciated! I was having same headers not found issue (xcode 4.5, PG 2.1.0, MountainLion) and went through ALL the google groups – instead of modding build files as reco’d, I completely uninstalled Phonegap/Cordova (just deleted did not run uninstall), follwed all the same install instructions again and for some reason it built fine (!). If you’re having header missing issues try this a few times just to be sure, making sure you delete all old Cordova files and have Xcode quit while doing so, – might save you time.

  10. Ive worked with all the pre releases but was a bit lost with the new terminal part. Thanks for posting this as it has helped me install the lastest version, Now lets Code !! :)

  11. This is a very well written article. I was able to setup my mac with your instructions in a very short amount of time. Keep up the good work and thank you so much for your detailed steps.

      • Do you know why the initial Cordova app index.html has the .js files in the body as opposed to the head? I tried another test run and that one again would not open a url. It would be nice to be able to document what exactly is happening so people can provide a solution. It was interesting too that when I created a second project I had a bunch of build errors in the original project.

  12. wow, you did a great job at explaining things (and making them work) from a newbie’s point of view. Congrats!

    A quick note, to grab screenshots, run the app in the simulator and then hit cmd+S, it’ll be saved on your desktop without frame, ready for iTunes Connect (make sure you using iPhone retina as “hardware”).

  13. Great artikel. it worked fine with me. I transformed my website to a App.

    I also added the * for opening websites, in a new screen, which could not be closed. Did you till now have a solution for this? you wrote something about a ChildBrowser plugin?

    I am working on a specific solution. I want to send an URL but actually not open the screen from that website (this URL will send information to a provider who will send a SMS, for example by the URL: https://www.mollie.nl/xml/sms/username=jan&password=jan&originator=0654385649&recipients=065342987&message=call reception.

    Do you have a suggestion how to solve this? I worked out something wich a timesetout and that worked fine within internet exploren but not within my app.

    • To open a page and keep it within the app, install the Childbrowser plugin. I have instructions for the download here, but I have not tested it for the latest 2.0+ versions of Cordova. However, another coder said he tried it and said it was easy to install.

  14. I have tried the guide below im running moutin lio 10.8.2 and Xcode and i have the command line tools installed and download pg2 from website when i go into the ios lib folder and issue the create command i get back -bash: create: command not found even though i do see the file their bare with me im comming from a windows background so maybe a step ive missed

  15. Hiya,

    Quick question… Have you successfully built & deployed any cordova-powered newsstand apps? If so, do you think you could share a magazine with me? I’m new to iOS development, but an old hand at standard Web Dev… Was hoping to use Cordova/Phonegap to power the Newstand Apps we’re building for iOS. :-)

    • I assume you mean the first step 3:

      3. This PhoneGap install requires the Xcode Command Line tools, so I opened Xcode to download it – Xcode Preferences > Downloads > Components > Command Line Tools > Install (115.4MB). Downloading this package will install copies of the core command line tools and system headers into system folders, including the LLVM compiler, linker, and build tools.

      Open up Xcode, which you downloaded from Apple App Store, then click on Preferences and then the other selections noted in order.

  16. Steve, I spent almost a week trying to figure out these steps. The documentation is horrible, and anything good I managed to find was for older versions of phonegap. This was EXACTLY what I needed and it all worked like a charm. I can’t tell you how perfect your instructions were… totally understandable and clear, and exactly what I needed. I see this was posted last year, but there is still nothing close to this good, because for whatever reason, you seem to be the only one, other than ME that needed to do it exactly THIS way. Anyway. THANK YOU, THANK YOU, THANK YOU!!!!!

  17. Hi Steve, thanks for the steps, v helpful. But I dont seem to have the cordova.plist so I cant add the externalHosts *

    Any ideas as I still get the following error when clicking the phonegap link. “The requested URL was not found on this server”

    Cheers

    Paul

    • The cordova.plist is provided after the .create command is invoked in the command line. You’ll want to open up all the folders until you find it, or run .create again.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.