Skip to content
Permalink
Browse files
CB-7158 - Fix geolocation for ios 8
Signed-off-by: Shazron Abdullah <shazron@apache.org>
  • Loading branch information
Wei Li authored and shazron committed Sep 9, 2014
1 parent 3bc05a4 commit 4102a332b0c6b0c3513370a4c030a32e46a51e10
Showing 1 changed file with 28 additions and 0 deletions.
@@ -73,6 +73,11 @@ - (BOOL)isAuthorized

if (authorizationStatusClassPropertyAvailable) {
NSUInteger authStatus = [CLLocationManager authorizationStatus];
#ifdef __IPHONE_8_0
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { //iOS 8.0+
return (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse) || (authStatus == kCLAuthorizationStatusAuthorizedAlways) || (authStatus == kCLAuthorizationStatusNotDetermined);
}
#endif
return (authStatus == kCLAuthorizationStatusAuthorized) || (authStatus == kCLAuthorizationStatusNotDetermined);
}

@@ -118,6 +123,21 @@ - (void)startLocation:(BOOL)enableHighAccuracy
return;
}

#ifdef __IPHONE_8_0
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { //iOS8+
__highAccuracyEnabled = enableHighAccuracy;
if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(@"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
}
return;
}
#endif

// Tell the location manager to start notifying us of location updates. We
// first stop, and then start the updating to ensure we get at least one
// update, even if our location did not change.
@@ -324,6 +344,14 @@ - (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)e
__locationStarted = NO;
}

//iOS8+
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(!__locationStarted){
[self startLocation:__highAccuracyEnabled];
}
}

- (void)dealloc
{
self.locationManager.delegate = nil;

49 comments on commit 4102a33

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a working solution? I modified all the files, but still I don't get a user position on iOS8. Build is working on iOS7 tough :(

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works, tested 100%.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you add the Info.plist additions needed? This is installed when you add the plugin. If you have an existing plugin, you will have to add it manually. See plugin.xml in this repo.

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I did. Can I send you an email so we get directly on touch?

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Create a new project
  2. Install the plugin
  3. Try the getCurrentPosition sample in the docs

See if that works first

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope :( no success at all :(

I am really desperate here...

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I modified. plugin.xml, CDVLocation.h and CDVLocation.m is there anything else?

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would even pay you to take a look at my project!

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I can't do that (get paid). Please do what I requested above, zip it up, and post it somewhere and post the link, I'll take a look.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have the latest code of the Geolocation plugin installed. Don't use the one in the registry, you will have to install this manually by git repo url. And like I mentioned the first time, you need to add the Info.plist additions that are needed.

This is all done for you with the latest code of the plugin if you install it, by git repo url.

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where I find the latest code?

https://github.com/apache/cordova-plugin-geolocation.git ?

and this is my command:

phonegap add plugin https://github.com/apache/cordova-plugin-geolocation.git

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@onlyurei
Copy link

@onlyurei onlyurei commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested it in iOS8, it works.

cordova plugin rm org.apache.cordova.geolocation
cordova plugin add https://github.com/apache/cordova-plugin-geolocation.git

For some reason it removes the CDVLocation.m from the compilation list, you need to revert that.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onlyurei you mean CoreLocation.framework? yeah that seems to be an issue with the tool itself, not sure how to fix that yet

@onlyurei
Copy link

@onlyurei onlyurei commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entries In XXX.xcodeproj/project.pbxproj:

979B00CA27D6412CB8C6CF74 /* CDVLocation.m in Sources / = {isa = PBXBuildFile; fileRef = E3B4F7C4AF8242A09E9BF8C1 / CDVLocation.m */; };

979B00CA27D6412CB8C6CF74 /* CDVLocation.m in Sources */,

Without these 2 lines, the plugin is not available to use in the app.

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I have to edit something more?

I get this error:

phonegap add plugin https://github.com/apache/cordova-plugin-geolocation.git

When I do so, I get the following error when trying to execute

[CDVCommandQueue executePending] [Line 158] FAILED pluginJSON = [
"Geolocation464702007",
"Geolocation",
"addWatch",
[
"0e571878-f89f-bb97-e6fa-c1e33bb92efb",
false
]
]

@onlyurei
Copy link

@onlyurei onlyurei commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, should be the problem I encountered as well:

ERROR: Plugin 'Geolocation' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.
2014-09-15 16:07:41.977 TransitMaster[18304:896800] -[CDVCommandQueue executePending] [Line 158] FAILED pluginJSON = [
"Geolocation172109477",
"Geolocation",
"getLocation",
[
false,
60000
]
]

As I said, you need to put back the two lines removed from XXX.xcodeproj/project.pbxproj where XXX is your Xcode project name.

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sry for beeing super noobish here, but which 2 lines in which file? :D

@onlyurei
Copy link

@onlyurei onlyurei commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me it's easy to spot the change in XXX.xcodeproj/project.pbxproj since it was in source control from the beginning of the project.

If you have that file in source control as well just revert the deletions related to CDVLocation.m in XXX.xcodeproj/project.pbxproj.

If not try add CDVLocation.m to the Compile Sources step in the Build Phases in the project settings.

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only find that file in the finder, and there I can't find source control :(

So what exactly do you mean by this: ? :D

If not try add CDVLocation.m to the Compile Sources step in the Build Phases in the project settings.

And I guess it also won't help if completely resetup my project, because as soon as I install the plugin, these to lines are missing?

@Leinadzet
Copy link

@Leinadzet Leinadzet commented on 4102a33 Sep 16, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx guys! I somehow got it to work! Great support here, have been trying that for days now....

@colonelchlorine
Copy link

@colonelchlorine colonelchlorine commented on 4102a33 Sep 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shazron does ios8 require that the users choose their location, or else the app's geolocation won't work at all? i tried using the master cordova geolocation plugin and my app didn't ask me for acceptance, and the location didn't work. as soon as i went with the lastest plugin version (with these fixes) the app asked me, and location worked perfectly.

is there a way to configure it so the app forces location services?

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 22, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colonelchlorine what do you mean exactly? Like if the user said no the first time, and you need to ask again?

@colonelchlorine
Copy link

@colonelchlorine colonelchlorine commented on 4102a33 Sep 22, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 23, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colonelchlorine ah yes I know what you are getting at. What you encountered was the default behavior on iOS 8 if you didn't ask it for the new permissions. It should call the error handler, no? If it did, there should be an error code.

@cxfeng1-zz
Copy link

@cxfeng1-zz cxfeng1-zz commented on 4102a33 Sep 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why there is a "return;" after request authorization?

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the geolocation for the JPEG format. Execution stops here and is picked up in the geolocation callback.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just updated to use geolocation version 0.3.10, but I'm not seeing the location permissions popup on iOS8. Is there something special I have to do to make that appear? Currently, I'm just getting a timeout error when I call getCurrentPosition.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check that you have the appropriate entries in your Info.plist, see the plugin's plugin.xml in this repo.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked, and I see this in the plist/dict, which I assume was added by the plugin:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string></string>

Is that's all that is needed in there for this?

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it seems I've got everything set up, but it's not providing the prompt with the changes that were pushed in 0.3.10 unfortunately. :/

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should clarify that this is through the cordova run ios command, in case there is any difference between that and building/archiving a full IPA release.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always try it with a new project, to eliminate other problems, and only install the plugin. I assure you it does work, but not sure what's going on with your setup yet.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shazron Here's a link to a brand new Cordova project that has the same issue: https://github.com/mhuggins/broken-cordova-geolocation-ios8-example

  • I'm using Cordova 3.6.3-0.2.13.

    ➜  test-project git:(master) npm show cordova version
    npm http GET https://registry.npmjs.org/cordova
    npm http 304 https://registry.npmjs.org/cordova
    3.6.3-0.2.13
    
  • I'm using org.apache.cordova.geolocation@0.3.10, as can be seen in the plugin.xml file.

  • I've confirmed that the HelloCordovoa-Info.plist file contains the appropriate permission setting.

    <key>NSLocationWhenInUseUsageDescription</key>
    <string></string>
    
  • I captured a screenshot demonstrating the error callback being hit from getCurrentPosition:
    img_2007

Hope this helps, thanks!

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just cloned your project, ran it, and it gave me the geolocation but I ran in Xcode
. Not sure what's going on with "cordova run ios" seems problematic (probably a bug).

  1. Cloned it
  2. Ran "cordova build"
  3. Ran "open -a Xcode platforms/ios" (doing this to avoid cordova run iOS)
  4. Tested on iOS Simulator 8.0 and 8.0 Device
  5. Got a geolocation immediately

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried it again with "cordova run ios"... it worked. It's more likely an actual timeout somehow.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll try running with the XCode approach to see if I get any different results. It seems odd that the timeout would only be consistently hit in iOS8 and not other devices. Admittedly, that may be an iOS8 issue over a Cordova issue, or may be completely incidental altogether, though I would be surprised from my personal reproduction rate of 100% on iOS8 vs. 0% on iOS6/7.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iOS 8 Simulator is buggy. html selects don't work, for example: https://issues.apache.org/jira/browse/CB-7651

I'm chalking this up to yet another iOS 8 Simulator bug. I always try to test on the device just in case. I know it's quite annoying however.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Sep 29, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I haven't tested on the iOS8 simulator at all, only on a legitimate device.

@premiumFrye
Copy link

@premiumFrye premiumFrye commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No luck witn NSLocationWhenInUseUsageDescription: always producing the key, but an empty string in the .plist , and iOS8.02 isn't recognizing that. Using PG Build, so suspect it's either an issue with their service, or potentially even iOS. See my post here:

http://community.phonegap.com/nitobi/topics/core-plugins-have-been-updated-on-phonegap-build#reply_14898031

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works 100%, I just re-tested it. Here's the repo I uploaded with my test project: https://github.com/shazron/GeoTest
Not sure about PhoneGap Build though, it's possible there might be a configuration error there.

The empty string is a red-herring -- it's ok to leave it empty. It's for a dev to explain why he/she needs the permission to their app user.

Using:

  1. cordova-cli 3.6.3-0.2.13
  2. cordova-ios 3.6.3
  3. org.apache.cordova.geolocation 0.3.10
  4. Xcode 6.0.1

Tested on:

  1. tested on iOS Simulator (iOS 7.1, 8.0)
  2. tested on iOS Device (8.0.2) - iPhone 6 Plus

Project created using:

  1. cordova create GeoTest foo.geotest.foo GeoTest
  2. cordova platform add ios
  3. cordova plugin add org.apache.cordova.geolocation
  4. cordova prepare
  5. open -a Xcode platforms/ios

When in Xcode, I tested using the Simulator and deployed to device.

When the app loads:

  1. Click on the GEO TEST button
  2. A permission dialog will show asking Allow | Don't Allow (see screenshot below)
  3. When you click Allow, you get an alert with your coordinates (see screenshot below)

s1
s2

@premiumFrye
Copy link

@premiumFrye premiumFrye commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, good to know about the empty value for NSLocationWhenInUseUsage! Thanks for the response, I'll try to figure what's making my app not work properly and shoot a message back if it's anything interesting.

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@premiumFrye please share if you figure it out, as I couldn't get the permission popup to appear in iOS8 with this change either.

@premiumFrye
Copy link

@premiumFrye premiumFrye commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhuggins When you go to privacy->geolocations is 'never' and 'when in use' showing up with neither selected, too?

@mhuggins
Copy link

@mhuggins mhuggins commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I was using a borrowed coworker's device to test, and he's out of town, so I'm unable to confirm. :( FWIW, the app I was working on was rejected by Apple for geolocation not working in iOS8 since the App Store submission timing lined up poorly with their release.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Oct 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhuggins please download the sample project I referenced above and test to confirm that it is working first, if it doesn't, it may give a clue (probably something to do with the environment, or different Xcode, not sure until tested)

@blinder
Copy link

@blinder blinder commented on 4102a33 Oct 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an interesting tidbit i found that when i re-installed the geolocation plugin, the CDVLocation.m wasn't added to the list of compiled sources in xcode. I had to manually add it there before getting geolocation to work

so under "Build Phases" i went under "Compiled Sources" then clicked the "+" navigated to the Plugins folder and added: CDVLocation.m to the list, saved the project, re-ran the simulator and it worked.

one other thing i found a little weird that with using a custom location that would sometimes cause a kCLErrorDomain error 0 with a 'null' error. When i switched the the "Apple" location in the Debug menu, it started working as expected.

@shazron
Copy link
Contributor

@shazron shazron commented on 4102a33 Oct 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably a CLI bug.
The Simulator wrt to Geolocation might be buggy. I always test with a device.

Please sign in to comment.