PhoneGap and Cordova with iOS 7

Now that it’s officially available, I wanted to share my experience running and building PhoneGap / Cordova applications on iOS 7.

Running Existing Apps

The first thing I tried to do after the upgrade process was to run the existing PhoneGap applications already installed on my phone. Good news: They run “as is” (with a minor cosmetic issues: see below).

Building and Deploying

Building and deploying new apps was also pretty straightforward. Here are the steps (I’m assuming PhoneGap 3):

  1. Install Xcode 5: the update is available in the App Store on your Mac.
  2. Start Xcode 5 before building your application to make sure Xcode downloads the required components. Before you can build a project using the PhoneGap or Cordova command line tool, you’ll also have to accept the new license agreement in Xcode 5.
  3. Build your PhoneGap application as usual on the command line:
    phonegap build ios
    
  4. Open the project (the .xcodeproj file in platforms/ios) in Xcode, and run it on your device.

The Status Bar Issue

On iOS7, all the applications are running full screen, and the status bar now overlays your application. As a result, it may cover some of your content or interfere with your header:

ios71


Different solutions have been discussed in the forums (here and here). Some of them involve native code to offset the web view. I think the simplest and cleanest solution is to add a 20px top margin to the document’s body using CSS. You can use version detection to avoid adding the margin if the application is running on iOS 6. Shazron posted a nice Gist with a simple solution:

function onDeviceReady() {
    if (parseFloat(window.device.version) === 7.0) {
          document.body.style.marginTop = "20px";
    }
}
 
document.addEventListener('deviceready', onDeviceReady, false);



Here is the result:

ios72

Cordova 3.1

Cordova 3.1 is expected soon (probably next week) with additional iOS 7 support:

  • Update to the splashscreen plugin to better support the status bar
  • Update to the Media and Media Capture plugins to handle the new Microphone access permissions
  • A fix to this bug (keyboard preferences)

Topcoat

iOS 7 is another reason to take a look at Topcoat, the new CSS toolkit that I have already covered and demonstrated multiple times in this blog. Topcoat’s flat design with no gradients or shadows fits perfectly with the new aesthetics of iOS7. Topcoat is just a set of CSS styles and works with any JavaScript framework: Backbone.js AngularJS, Ember, etc.

63 Responses to PhoneGap and Cordova with iOS 7

  1. David Mead September 19, 2013 at 10:13 am #

    I think for the version detection you should use “>= 7.0″ so to be more future forward.

    Thanks for the great article.

  2. geminiimatt September 19, 2013 at 11:23 am #

    imho: this should say greater than or equal to 7 to future proof it as much as possible.

    • Steve November 30, 2013 at 10:21 am #

      lol, i first thought you’re Bill Cosby.

  3. geminiimatt September 19, 2013 at 11:24 am #

    looks like you can delete my post. “david mead” appears to have the same idea.

  4. Shazron September 19, 2013 at 3:08 pm #

    Thanks David Mead and geminiimatt – I’ve updated the gist

  5. Lee Crossley September 20, 2013 at 6:53 am #

    Use this in conjunction with my iOS7 navigation styles: http://ilee.co.uk/ios7-navigation-bar-using-css/ although you’ll want to add the margin top to the header elements too.

  6. Mayron Cachina September 20, 2013 at 9:37 am #

    cool! good to know a few bugs, I will start migrating to some apps I have on iOS6 .. I’ve seen it will be a fairly complex task :)

  7. Michael Lesher September 20, 2013 at 1:44 pm #

    I like Topcoat, but given that Bootstrap 3 has flattened its design and it includes many additional elements, is there a reason that you are suggesting Topcoat so frequently? Besides it’s own merits against Bootstrap, is there a PhoneGap specific reason to opt for Topcoat vs. Bootstrap?

    • Andy Fuchs September 23, 2013 at 12:45 pm #

      @Michael Lesher: I can’t answer your question, but I for one, don’t want my app to look as everybody else’s app. That’s the problem with Bootstrap AND Topcoat ‘as is’ right now.

      So you have to create your own theme (or parts of it). While Bootstrap uses well-know CSS or LESS as stylesheet language, Topcoat decided to go for Stylus. While I might understand why they did, for me that’s a pita, since I have to (again) learn something new just to get things done…

  8. Guy September 23, 2013 at 3:09 am #

    Anyone know if phonegap 1.7 not supported in ios 7 on iPad ?
    my app stopped to work after iOS 7 release.

  9. Ronald September 23, 2013 at 10:47 am #

    There also is an issue with iPhone apps running in the iPad’s compatibilty window. They’ll take the iPad’s width and height. Not a Cordova bug but an UIWebkit issue…

    The workaround seems to be to remove ‘width=device-width, height=device-height’ from the meta viewport tag.

  10. Tony Hursh September 23, 2013 at 11:11 am #

    Personally, I disagree that adding a browser/platform-sniffing hack to every single app built from now on is anything like a “clean” solution.

    This should be fixed at the Cordova level.

    • David Mead September 23, 2013 at 2:15 pm #

      I couldn’t agree more Tony. But sometimes you just need something to work regardless of how messy it is.

    • Shazron September 24, 2013 at 3:20 pm #

      Ideally, yes – we could make the webview stack below the status bar like iOS 6 and below, but it’s more of a choice right now to keep it as is so the background “shows through” to the status bar (per the iOS UI Guidelines)

  11. Mike September 23, 2013 at 3:34 pm #

    How can this be utilized with inAppBrowser. I use jQuery Mobile and applied the 20px to .ui-bar-a, but my inAppBrowser window still has the problem.

    Thanks

    • Brian October 7, 2013 at 11:02 am #

      Hi,

      Although I am not using jquery mobile for the project. But I did fix the current conflict between inAppBrowser and status bar in ios7. I use native hacker way not using js to set margin-top, because since it only happens in ios no need to put in shared web code with android and other platform in my opinion.

      You can add these native hacker code in your main[viewcontroller.m]:
      - (void)viewWillAppear:(BOOL)animated
      {
      // View defaults to full size. If you want to customize the view’s size, or its subviews (e.g. webView),
      // you can do so here.

      NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@”.”];

      if ([[vComp objectAtIndex:0] intValue] >= 7) { // iOS 7 or above

      CGRect oldBounds = [self.view bounds];

      CGRect newWebViewBounds = CGRectMake( 0, -20, oldBounds.size.width, oldBounds.size.height-20 );
      CGRect newWebViewFrame = CGRectMake(0, 20, oldBounds.size.width, oldBounds.size.height-20);

      [self.webView setBounds:newWebViewBounds];
      [self.webView setFrame:newWebViewFrame];

      }

      [super viewWillAppear:animated];
      }

      then you need to modify the cordova library inappbrowser library in method – (void)createViews:

      CGRect webViewBounds = self.view.bounds;

      webViewBounds.size.height -= FOOTER_HEIGHT;

      NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@”.”];

      if ([[vComp objectAtIndex:0] intValue] >= 7) { // iOS 7 or above

      CGRect newWebViewBounds = CGRectMake( 0, 20, webViewBounds.size.width, webViewBounds.size.height-20 );

      self.webView = [[UIWebView alloc] initWithFrame:newWebViewBounds];

      }else{
      self.webView = [[UIWebView alloc] initWithFrame:webViewBounds];
      }

      self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

      [self.view addSubview:self.webView];
      [self.view sendSubviewToBack:self.webView];

      It is basically the same way to set bounds to webview, but since if you change anything about bounds and frame size and position in view, after it calling children view, it will init your parent view. So we have to not change anything about view and change the webview bounds size and frame position to make it work. Hopefully help you as well, but jQuery Mobile not a nice guy to work with :(

  12. Federico Torre September 24, 2013 at 5:48 pm #

    Just incase anyone is using this with jquery mobile, (or a fixed header with other items in it!), here’s what I did. It adds the margin of 20px to each object within your header.

    if (device.platform == “iOS” && parseFloat(device.version) >= 7.0) {
    $(‘.ui-header > *’).css(‘margin-top’, function (index, curValue) {return parseInt(curValue, 10) + 20 + ‘px’;});
    }

    • isaax2 October 8, 2013 at 10:05 am #

      it works with jquerymobile, tested on ios7, xcode5, cordova 3.1

    • hanism October 9, 2013 at 6:31 am #

      sorry for the noob question. i don’t know where to put your suggested code..huhu..
      thanks

  13. Sam September 25, 2013 at 4:36 am #

    Worth mentioning that in order to use device.version hack, your app needs the device plugin installed:

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

  14. Keenan September 28, 2013 at 7:29 pm #

    If you are still running Cordova 2.X here is plugin to ask for and check the iOS7 microphone permission (works nicely on both iOS7 and <7

    https://github.com/keenan/Cordova-Phonegap-Record-Permission

  15. jarrett September 30, 2013 at 5:21 pm #

    Hi. I am a writer/graphic designer that has constructed an html based choose your own adventure style game. The graphics are meant to emulate the style of 80s games…all static imagery.

    There are about 100 html pages, and about 30 graphics. I am searching for the simplest way to get this content into shape for sale on the app store. Being a little clunky won’t hurt this game since it’s based on an era that was, in fact, pretty clunky technologically. I run the adboe cc suite, and am about to purchase an apple developer’s license.

    Can anyone give me any hints or feedback that will help me to get this game ready to go? The only real additions i would like to add would be links to the website and links to purchase other 8 bit adventures on itunes.

    So to sum it up, my game is made of images, text, and hyperlinks. Nothing more…any help would be greatly appreciated, as the production of this game is really important for me. I’m in a bad way, but this story in the game should rivet most kids from the 10-13 year old range.

    Regards!

  16. Kamil October 1, 2013 at 2:38 am #

    This is not a bug, this is a future :). Web views has separate option to manage status bar visibility.
    Go to your info.plist file (in xcode 5), add new property called: “View controller-based status bar appearance” , set it to NO, and rerun your project.

    • okor October 1, 2013 at 11:22 am #

      Just to expand on this solution a little:
      - This will hide the status bar completely.
      - The -info.plist file will be located in the “Resources” directory.
      Via xcode or manually
      - Add the “View controller-based status bar appearance” entry, with a boolean value of NO.
      - Also set the “Status bar is initially hidden” boolean value to YES
      - clean the build / rebuild with xcode or rebuild with phonegap build
      Fin

    • isaax2 October 8, 2013 at 10:09 am #

      It works, but somentimes you want to keep the status bar in your app without overlapping

  17. jarrett October 1, 2013 at 2:26 pm #

    Hi. Great blog. How can I set it so that when someone quits my app and returns to it later, that it is still on the same html page?
    Regards,
    Jarrett

  18. Jof Arnold October 2, 2013 at 11:04 am #

    May I suggest the following instead:

    if (device.platform is ‘iOS’) and (parseInt(device.version,10) >= 7)

    That way you allow for, e.g., 7.0.3 with confidence

    (Code above is coffeescript but you get the idea)

  19. Abhishek Mishra October 7, 2013 at 2:07 am #

    Your solution is better than the native hacks suggested. When I tried the native hack of 20px offset from top, it used to happen everytime I opened a Child Browser. You solution works great.

    One Addition. I used paddingTop in my Sencha Touch App. Apparently, the height defined is 100% because of which the entire screens moves down by 20px. Works great when I use padding.

    if (parseFloat(window.device.version) == 7.0) {
    document.body.style.paddingTop = “20px”;
    }

  20. David S. October 7, 2013 at 3:51 am #

    Thanks for this tip, but it does not seem to work with jQuery Mobile UI… :(

    • isaax2 October 8, 2013 at 10:14 am #

      check the Federico Torre coment below…

      $(‘.ui-header > *’).css(‘margin-top’, function (index, curValue) {return parseInt(curValue, 10) + 20 + ‘px’;});

      • Paul October 18, 2013 at 1:39 am #

        This didn’t work for me. Which version of JQM are you using?

        I found @okor solution better because I didn’t have to mess with the layout after pushing the body 20px. If you don’t need the status bar in your app this would be the quickest way.

        The only other way I know would be to hack away at the CSS for JQM.

  21. giacomo upCreative October 7, 2013 at 10:18 am #

    Really useful post.. Thanks to share it !

  22. Nathan October 7, 2013 at 9:40 pm #

    Don’t add 20px to body. Just make navigation bar 64px and change status bar color to what you want for ios7.

  23. Anthony Trimble October 9, 2013 at 12:26 pm #

    Thanks for posting this.

  24. Leon October 9, 2013 at 1:05 pm #

    Out of interest, some of the apps you tested, did some of them use local storage? I am having issues after upgrading to ios7 with phonegap 3.1 that the tx.executeSql does not seem to run. However doing a check in the background localstorage is supported.

  25. David Bopp October 21, 2013 at 4:17 pm #

    Would be good to mention that the basic device information plugin is required to get that code running:
    information: http://www.raymondcamden.com/index.cfm/2013/7/19/PhoneGap-30-Released–Things-You-Should-Know
    plugin: https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

  26. Gareth November 7, 2013 at 9:36 am #

    In your AppDelegate.m file add the following to remove the status bar from your app in IOS7:

    - (BOOL)statusBarHidden
    {
    return YES;
    }

    Also add property: (key: Status bar is initially hidden, value: YES) to your project Info list in Custom iOS Target Properties

    No more annoying status bar inside your app and no having to mess with CSS or JS to get desired effect!

  27. Vasily November 20, 2013 at 1:05 am #

    Hi guys, thank you for the article.

    I have a problem with Phonegap 3.1.0: when I run my page in Safari (iOS), I have configured the status bar to be ‘black-translucent’… and for my page that results in white font for status bar…. When I run the same page under Phonegap, the status bar is translucent, but font color is BLACK. How to make it white, so my page will look like in Safari?

    Thank you!

  28. Per Quested Aronsson December 21, 2013 at 4:41 pm #

    Hello, I have the opposite problem: I have already built a full-screen landscape app 1024*768 pixels. I would like to use the full screen if possible. If not, I would prefer it if the status bar covered the top 20px of the app rather than pushing it down 20px. The bottom 20 px are far more important in this app. However, when I build the app using Phonegap Build with PG 3.1, the app view is automagically pushed down 20 px. How can I *prevent* that from happening?

  29. Jack Stanton January 12, 2014 at 7:40 pm #

    I need a sanity check regarding the iOS WebViews. I have project built with iOS. When I look at the directions provided by phonegap, it seems like everything under Adding Cleaver to xCode Project already has been done. No need to go through any of the steps listed for Adding Cleaver to xCode, is that right?

    I know it must be easy, but I have not been able to get webViews working in phonegap iOS.

    Any information helping to get that going will be much appreciated. Thank you.

    There will be more to do after this is done, but this first “easy” step is my current challenge.

    It seems like the directions for embedding WebView into iOS are very much out of date. at http://docs.phonegap.com/en/edge/guide_platforms_ios_webview.md.html#iOS%20WebViews

  30. Sam January 16, 2014 at 8:18 am #

    I just built an app using jQuery mobile and simply set the following in config.xml – status bar not visible at all:

    Used Cordova 3.1

    • Sam January 16, 2014 at 8:22 am #

      Comment got sanitized – just add appropriate angle brackets around:

      preference name=”fullscreen” value=”true”

  31. Sean Walsh January 28, 2014 at 5:43 pm #

    Topcoat is not flat design.

  32. kilim March 24, 2014 at 5:14 am #

    Thanks David Mead and geminiimatt

  33. André Morales March 31, 2014 at 2:14 pm #

    Great tip thanks!

  34. s.w.pollux April 13, 2014 at 11:31 am #

    using a cordova plugin to fix this issue.

    cordova plugin add org.apache.cordova.statusbar

    This pulls the necessary code from the plugin repository into our application. Now we’re ready to invoke the plugin in our code:

    $( document ).on( “deviceready”, function(){
    StatusBar.overlaysWebView( false );
    StatusBar.backgroundColorByName( “gray” );
    });

    the status bar overlay being turned off, as well as the background color of the status bar being changed to better fit your application

    • Oscar July 25, 2014 at 11:54 pm #

      workeep great! Thanks

  35. John April 21, 2014 at 11:55 am #

    @Per Quested Aronsson “+1″ for “automagically”. Awesome!

  36. Dave April 28, 2014 at 4:29 am #

    Hello,

    I would like to have your help please.

    I would like to use adobe phonegap build at this address https://build.phonegap.com/plugins

    For create a notification simple notification in android and ios
    do you have a simple zip to send me where i can run to see how he work.

    I am totaly lost since many day and dont find the solution the notification no work

    I hope you can help me

    Thank you a lot for your help

  37. Louis May 13, 2014 at 4:17 pm #

    How can I call the core device plugin (that seems to be required) on a Phonegap Build app ? (maybe with something like : )

  38. moto June 2, 2014 at 1:44 pm #

    Hi guys,
    I’m building SPA(single page app) using backbone.js(1.1.2) and jqm(1.4.2), and I’m experiencing strange things when browsing web site with Iphone( running IOS7) , basically my app just won’t load.. it has some issues with history.. how much I was able to understand this is deliberated restriction from Apple. Does anyone has workaround for this ????

  39. Praveen June 19, 2014 at 7:39 am #

    Actually this will work, but it will move the body 20px down and introduce the scroll. Any thoughts to fix this?

  40. Bill SerGio June 21, 2014 at 6:13 pm #

    Hi,

    Read my article and free source code on creating the Frosted Look of an iOS7 Panel in html5.

    http://www.sergioapps.com/iOS7_Frosted_Panel.html

    Bill SerGio

  41. http://www.youtube.com/watch?v=cazfivdLmG0 July 10, 2014 at 12:42 pm #

    I’m excited to find this page. I need to to thank you for your time for
    this particularly wonderful read!! I definitely appreciated every bit of it and i also have
    you book marked to check out new things on your site.

Trackbacks/Pingbacks

  1. DUSTIN.iO » Code Snip: Dealing with PhoneGap, jQuery Mobile and iOS 7 status bars - October 4, 2013

    [...] easiest way to handle this is discussed here, but if you’re using jQuery Mobile in tandem with PhoneGap/Cordova, you’ll need to make [...]

  2. New Version of My Halloween PhoneGap App | ANDREW TRICE - October 7, 2013

    [...] the application. You’ll need to update your UI on iOS 7, so there are no UI issues. Check out this post from Christophe Coenraets for details regarding creating PhoneGap apps for iOS [...]

  3. Converting a Hybrid Mobile Project to XCode 5 & iOS7 | UI Guy - November 1, 2013

    [...] next problem wasn’t fatal, but it sure was ugly. Christophe Coenraets provides an overview of the overlapping status-bar issue. In his case, he wanted to see it, but solve the spacing [...]

  4. Links for October 31st through November 3rd - November 4, 2013

    [...] PhoneGap and Cordova with iOS 7 – Now that it’s officially available, I wanted to share my experience running and building PhoneGap / Cordova applications on iOS 7. [...]

  5. PhoneGap Tutorial: Fix the status bar issue in iOS 7 - November 29, 2013

    [...] The article can be found here. [...]

  6. PhoneGap and Cordova with iOS 7 | Christophe Coenraets | Elog - April 29, 2014

    […] PhoneGap and Cordova with iOS 7 | Christophe Coenraets. […]

  7. PhoneGap and Cordova with iOS 7 | Christophe Coenraets - appgong - June 25, 2014

    […] PhoneGap and Cordova with iOS 7 | Christophe Coenraets […]

  8. Developer’s Guide to the iOS Status Bar for PhoneGap : Devgirl's Weblog - July 31, 2014

    […] are different ways to handle this iOS7 change in your applications. One common solution on the web side is to offset the application content by 20 pixels from the top to account for the […]

Leave a Reply

css.php