Cordova GeoLocation Plugin doesn't work with Ionic on iOS 10

Hi guys.
I am trying to make Cordova GeoLocation plugin to work with Ionic on iOS 10 and tried every single suggestion I could find in this forum, but nothing seems to resolve my problem.

The code I am trying to run can be found in my GitHub. It’s based on a tutorial from @Gajotres.

When I run the code in the browser or in the Ionic View App, everything works fine. But when I try to deploy the exactly same code on my iPhone 6 (iOS 10) with Xcode, no gps position is returned. Based on the Xcode logs (details below), apparently, the $ionicPlatform.ready() function is not even being executed.

What I’ve tried so far (nothing worked):

  1. Whitelist setup on index.html (Content-Security-Policy meta tag) and config.xml files;
  2. Removed iOS platform from Cordova and added it again;
  3. Updated Node.js to the latest stable version (6.6.0);
  4. Reinstalled all the Cordova plugins;
  5. Started my project from scratch;
  6. Manually added NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription tags in the info.plist file;
  7. Configured the Google Maps API key in the index.html file (this key is not set in the GitHub repository for obvious reasons);
  8. Double checked the plugins list in the config.xml file of my project’s root dir;
  9. Double checked the plugins list in the package.json file of my project’s root dir;
  10. Double checked the plugins list in the fetch.json file of my project’s plugin dir;
  11. Double checked the plugins list in the ios.json file of my project’s plugin dir;
  12. Double checked the geo-location plugin is called inside the $ionicPlatform.ready() function;
  13. Tested in the browser and in the Ionic View App (as I’ve already mentioned above);

Here are the logs from the Xcode console:

2016-10-01 14:51:07.713252 IonicGeolocation[1973:736983] DiskCookieStorage changing policy from 2 to 0, cookie file: file:///private/var/mobile/Containers/Data/Application/55DCC1DC-518E-44AB-A5EE-B13A612A3A92/Library/Cookies/Cookies.binarycookies
2016-10-01 14:51:07.798503 IonicGeolocation[1973:736983] Apache Cordova native platform version 4.2.1 is starting.
2016-10-01 14:51:07.801641 IonicGeolocation[1973:736983] Multi-tasking -> Device: YES, App: YES
2016-10-01 14:51:07.939389 IonicGeolocation[1973:736983] Using UIWebView
2016-10-01 14:51:07.941566 IonicGeolocation[1973:736983] [CDVTimer][handleopenurl] 0.113010ms
2016-10-01 14:51:07.945461 IonicGeolocation[1973:736983] [CDVTimer][intentandnavigationfilter] 3.796995ms
2016-10-01 14:51:07.945656 IonicGeolocation[1973:736983] [CDVTimer][gesturehandler] 0.111997ms
2016-10-01 14:51:07.973740 IonicGeolocation[1973:736983] [CDVTimer][splashscreen] 28.012991ms
2016-10-01 14:51:07.987673 IonicGeolocation[1973:736983] [CDVTimer][statusbar] 13.790011ms
2016-10-01 14:51:07.989217 IonicGeolocation[1973:736983] [CDVTimer][keyboard] 1.411021ms
2016-10-01 14:51:07.989325 IonicGeolocation[1973:736983] [CDVTimer][TotalPluginStartup] 47.910988ms
2016-10-01 14:51:08.517934 IonicGeolocation[1973:736983] Resetting plugins due to page load.
2016-10-01 14:51:09.830225 IonicGeolocation[1973:736983] Finished load of: file:///var/containers/Bundle/Application/B66B4145-7BBF-4D30-8BDA-EBF959E9948C/IonicGeolocation.app/www/index.html
2016-10-01 14:51:18.070000 IonicGeolocation[1973:736983] THREAD WARNING: ['Device'] took '32.822998' ms. Plugin should use a background thread.
2016-10-01 14:51:18.600105 IonicGeolocation[1973:736983] deviceready has not fired after 5 seconds.
2016-10-01 14:51:18.600215 IonicGeolocation[1973:736983] Channel not fired: onCordovaInfoReady

Note 1: I could’t find any record indicating the GeoLocation plugin has started in the logs (check the “CDVTimer” lines above);
Note 2: It seems that the “device ready” event is not being fired;
Note 3: The device plugin has logged an warning (“Plugin should use a background thread.”);

This is my Cordova plugins list:

cordova-plugin-compat 1.0.0 "Compat"
cordova-plugin-console 1.0.4 "Console"
cordova-plugin-device 1.1.3 "Device"
cordova-plugin-geolocation 2.3.0 "Geolocation"
cordova-plugin-splashscreen 4.0.0 "Splashscreen"
cordova-plugin-statusbar 2.2.0 "StatusBar"
cordova-plugin-whitelist 1.3.0 "Whitelist"
ionic-plugin-keyboard 2.2.1 "Keyboard"

This is my Ionic environment (ionic info):

Cordova CLI: 6.3.1
Ionic Framework Version: 1.1.0
Ionic CLI Version: 2.0.0
Ionic App Lib Version: 2.0.0
ios-deploy version: 1.9.0 
ios-sim version: 5.0.8 
OS: Mac OS X El Capitan
Node Version: v6.6.0
Xcode version: Xcode 8.0 Build version 8A218a

Am I missing something? Any ideas?
Thanks.

1 Like

After further investigation, I’ve noticed that the “allow” geo-location pop-up is only shown when I click the “home” button and re-enter the app. Only when I allow the app to get my geo-location and after I’ve re-entered the app, the $ionicPlatform.ready() function is called. I could confirm that by the exhibition of the spinner “Acquiring location!” which is shown in my $ionicPlatform.ready() function:

app.controller('MapController', function($scope, $cordovaGeolocation, $ionicLoading, $ionicPlatform) {
     
    $ionicPlatform.ready(function() {
         
        $ionicLoading.show({
            template: '<ion-spinner icon="bubbles"></ion-spinner><br/>Acquiring location!'
        });
         
        var posOptions = {
            enableHighAccuracy: true,
            timeout: 20000,
            maximumAge: 0
        };
        $cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) {
            var lat  = position.coords.latitude;
            var long = position.coords.longitude;
             
            var myLatlng = new google.maps.LatLng(lat, long);
             
            var mapOptions = {
                center: myLatlng,
                zoom: 16,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };          
             
            var map = new google.maps.Map(document.getElementById("map"), mapOptions);          
             
            $scope.map = map;   
            $ionicLoading.hide();           
             
        }, function(err) {
            $ionicLoading.hide();
            console.log(err);
        });
    });               
});

I’ve followed this tutorial to access my app’s logs and discovered 2 erros were happening:

  1. Refused to load gap://ready because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.
  2. PositionError {code: 3, message: “Position retrieval timed out.”, PERMISSION_DENIED: 1, POSITION_UNAVAILABLE: 2, TIMEOUT: 3}

The evidences from the above errors are shown below:

image

image

I’ll continue the investigation based on these new discoveries. Any help would be appreciated. :wink:

Finally!
Found some issues regarding Content-Security-Policy (CSP) and the “gap://ready” error I’ve found previously:

  1. password popup never shows on iOS10 #501;
  2. White screen on iOS 10 (new) #7052;
  3. White screen on iOS 10 #6928;

Just replaced my CSP meta tag from this …

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

… to this (notice the “gap:” in the “default-src” attribute) …

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

… and everything worked fine.

My GitHub repository is already updated with the correct CSP.

1 Like

I tried the same. It does not work! @cballock

It does work. Have you tried my demo code? @siddhartha

Got it working. Thanks.

Thanks bro .Its perfect working .