Tuesday, January 17, 2017

Gotcha of the Day: iOS Cordova App running in iSimulator Hangs on Splashscreen

I recently submitted Cordova iOS to iTunes, only to have it rejected because the app was hanging on startup. Turns out, the app worked fine on a real device, but on a simulator, the app's splashscreen wouldn't ever be hidden.

On the simulator, I did notice that if I returned 'home' and relaunched the app, it did function. It was all very confusing.

I was already working around this quirk in the splashscreen plugin:

The config.xml file's AutoHideSplashScreen setting must be false. To delay hiding the splash screen for two seconds, add a timer such as the following in the deviceready event handler

After further debugging, I learned that:

 navigator.splashscreen.hide();

was being called, yet, it wasn't having any effect.

To add insult to injury, the IO Simulator's console log wasn't showing the output of JavaScript's console.log(...) messages. The 'debugging' above involved using old school alert statements.

I solved the mystery of the missing console.log statements by following the instructions here. I'd totally forgotten that you can remotely monitor a web instance from within Safari. Frankly, it's sweet functionality, even if a bit non-intuitive.

  1. On your real iDevice or in iOS simulator go to Settings > Safari > Advanced and turn on Web Inspector.
  2. Desktop Safari: Safari > Preferences > Advanced and select the Show develop menu in menu bar checkbox.
  3. Now that you have either iOS Simulator open or your iDevice connected to your mac start using web inspector on your website: On your mac, open Safari and go to Develop

Along with my new found console.log statements, I saw the following message being repeatedly blurted out:

Refused to load gap://ready because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.

Eager to fix *something*, even if it's not the splashscreen bug, I Googled for this message. I found this discussion, which as the message itself suggests, shows that the Content-Security-Policy meta tag needs to be updated.

To shut the app up, I went ahead and updated my CSP to be:

<meta http-equiv="Content-Security-Policy" 
   content="default-src * 'self'; style-src * 'self' 'unsafe-inline'; script-src * 'self' 'unsafe-inline' 'unsafe-eval'">

I relaunched the app, and not only did the message disappear, but the call to navigator.splashscreen.hide() worked!

And of course, this all makes sense now: the call to hide the splashscreen was failing due to a lack of permission by the page. I added the permissions and things were back to working.

Why this was failing in the simulator and not a device, I can't really say. But I'm just glad it's working.

No comments:

Post a Comment