Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-20217] iOS: Ti.Geolocation.hasGeolocationPermission() and Ti.Geolocation.getCurrentPosition() are not working on IOS 7 - fix for TI_USE_KROLL_THREAD #7667

Merged
merged 3 commits into from
Feb 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion apidoc/Titanium/Geolocation/Geolocation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ methods:
summary: Returns `true` if the app has location access.
parameters:
- name: authorizationType
summary: Types of geolocation's authorizations. This is an iOS only parameter and is ignored on Android.
summary: |
Types of geolocation's authorizations. This is an iOS 8 and above only parameter and is ignored on
Android and iOS 7.
constants: [Titanium.Geolocation.AUTHORIZATION_ALWAYS,Titanium.Geolocation.AUTHORIZATION_WHEN_IN_USE]
type: Number
returns:
Expand Down
3 changes: 2 additions & 1 deletion iphone/Classes/GeolocationModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
CLLocationManager *locationManager;
CLLocationManager *tempManager; // Our 'fakey' manager for handling certain <=3.2 requests
CLLocationManager *locationPermissionManager; // used for just permissions requests

CLLocationManager *iOS7PermissionManager; // specific to iOS7 to maintain parity with iOS8 permissions behavior.

CLLocationAccuracy accuracy;
CLLocationDistance distance;
CLLocationDegrees heading;
Expand Down
56 changes: 47 additions & 9 deletions iphone/Classes/GeolocationModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ -(void)_destroy
[self shutdownLocationManager];
RELEASE_TO_NIL(tempManager);
RELEASE_TO_NIL(locationPermissionManager);
RELEASE_TO_NIL(iOS7PermissionManager);
RELEASE_TO_NIL(singleHeading);
RELEASE_TO_NIL(singleLocation);
RELEASE_TO_NIL(purpose);
Expand Down Expand Up @@ -824,15 +825,16 @@ -(CLLocationManager*)locationPermissionManager

-(NSNumber*)hasLocationPermissions:(id)args
{
id value = [args objectAtIndex:0];

ENSURE_TYPE(value, NSNumber);

CLAuthorizationStatus currentPermissionLevel = [CLLocationManager authorizationStatus];
CLAuthorizationStatus requestedPermissionLevel = [TiUtils intValue: value];
BOOL locationServicesEnabled = [CLLocationManager locationServicesEnabled];

return NUMBOOL(locationServicesEnabled && currentPermissionLevel == requestedPermissionLevel);
CLAuthorizationStatus currentPermissionLevel = [CLLocationManager authorizationStatus];
if ([TiUtils isIOS8OrGreater]) {
id value = [args objectAtIndex:0];
ENSURE_TYPE(value, NSNumber);
CLAuthorizationStatus requestedPermissionLevel = [TiUtils intValue: value];
return NUMBOOL(locationServicesEnabled && currentPermissionLevel == requestedPermissionLevel);
} else {
return NUMBOOL(locationServicesEnabled && currentPermissionLevel == kCLAuthorizationStatusAuthorized);
}
}

-(void)requestAuthorization:(id)value
Expand All @@ -841,9 +843,36 @@ -(void)requestAuthorization:(id)value
[self requestLocationPermissions:@[value, [NSNull null]]];
}

- (void)requestLocationPermissioniOS7:(id)args {
// Store the authorization callback for later usage
if([args count] == 2) {
RELEASE_TO_NIL(authorizationCallback);
ENSURE_TYPE([args objectAtIndex:1], KrollCallback);
authorizationCallback = [[args objectAtIndex:1] retain];
}

if (!iOS7PermissionManager) {
iOS7PermissionManager = [CLLocationManager new];
iOS7PermissionManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
iOS7PermissionManager.delegate = self;
}

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
// iOS7 shows permission alert only when location update is requested. Here we trick iOS7 to show
// permission alert so that our API is in parity with iOS8+ behavior.
[iOS7PermissionManager startUpdatingLocation];
} else {
[self locationManager:iOS7PermissionManager didChangeAuthorizationStatus:[CLLocationManager authorizationStatus]];
}
}

-(void)requestLocationPermissions:(id)args
{
if (![TiUtils isIOS8OrGreater]) {
// It is required that delegate is created and permission is presented in main thread.
TiThreadPerformOnMainThread(^{
[self requestLocationPermissioniOS7:args];
}, NO);
return;
}

Expand Down Expand Up @@ -1083,6 +1112,10 @@ - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatu
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:
NUMINT([CLLocationManager authorizationStatus]),@"authorizationStatus",nil];

if ([manager isEqual:iOS7PermissionManager] && (status != kCLAuthorizationStatusNotDetermined)) {
[manager stopUpdatingLocation];
}

// Still using this event for changes being made outside the app (e.g. disable all location services on the device).
if ([self _hasListeners:@"authorization"]) {
[self fireEvent:@"authorization" withObject:event];
Expand Down Expand Up @@ -1117,7 +1150,12 @@ - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatu

//Using new delegate instead of the old deprecated method - (void)locationManager:didUpdateToLocation:fromLocation:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if ([manager isEqual:iOS7PermissionManager]) {
// Used only to simulate permission alert. So ignore this update.
return;
}

NSDictionary *todict = [self locationDictionary:[locations lastObject]];

//Must use dictionary because of singleshot.
Expand Down