Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

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

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2016-02-02T08:52:52.000+0000
Affected Version/sRelease 5.1.1
Fix Version/sRelease 5.2.0
ComponentsiOS
Labelsqe-5.2.0
Reporter Ricardo Ramirez
AssigneeSrikanth Sombhatla
Created2016-01-09T01:36:09.000+0000
Updated2016-02-02T22:20:40.000+0000

Description

Issue Description

Geolocation popup permission is not triggered by Ti.Geolocation.hasGeolocatinPermission() Ti.Geolocation.hasGeolocatinPermission() does not work on iOS 7. It returns true before permission has been determined. Once it is determined it does not return the right value. Ti.Geolocation.requestLocationPermissions() never calls the callback on iOS 7.

TestCase

Create a new Alloy default Application

Open views/index.xml

Replace the inside with the next code:

<Alloy>
	<Window class="container" id="win">
		<View>
			<View class="container2">
				<Button class="btn" title="Check Permission" onClick="checkPermission" />
				<Button class="btn" title="Request Permission" onClick="requestPermission" />
				<Button class="btn" title="Check & Request Permission" onClick="checkRequestPermission" />
				<Button class="btn" title="Get Current Position" onClick="getCurrentPosition" />
			</View>
		</View>
	</Window>
</Alloy>

Open controllers/index.js

Replace the inside with the next code:

$.win.open();

function checkPermission(){
	if(Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)){
		Ti.API.info("APP HAS PERMISSION");	
	}else{
		Ti.API.info("APP DOES NOT HAVE PERMISSION");
		requestPermission();
	}
}

function requestPermission(){
	Ti.API.info("REQUESTING PERMISSION");
	Ti.Geolocation.requestLocationPermissions(Titanium.Geolocation.AUTHORIZATION_WHEN_IN_USE,function(e){
		Ti.API.info("INSIDE CALLBACK");
		if(e.success){
			Ti.API.info("PERMISSION GRANTED");
		}else{
			Ti.API.info("PERMISSION DENIED");
		}
	});
}

function checkRequestPermission(){
	checkPermission(requestPermission);
}

function getCurrentPosition(successHandler,errorHandler){
	Ti.Geolocation.getCurrentPosition(function(result){
		if (result.error) {
			Ti.API.info("GetCurrentPosition Error");
		}else{
			Ti.API.info("GetCurrentPosition returned" + JSON.stringify(result));
		}
	});
}
#open the tiapp.xml file and add the next lines inside ios/plist/dict
                <key>NSLocationWhenInUseUsageDescription</key>
                <string>Testing Location in use </string>

Run

Steps to Reproduce

Press "Check Location Permission" button which calls Ti.Geolocation.hasLocationPermissions(). It should return true and you should see "APP HAS PERMISSION" output.

Press "Request Geolocation Permission" which calls Ti.Geolocation.requestLocationPermissions() You should see "REQUESTING PERMISSION" in your output.

Third button calls Ti.Geolocation.getCurrentPosition() to get users current position which is what triggers geolocation permission popup to show. If you grant permission in the popup then press "Check Location Permission" button again and you should see "APP DOES NOT HAVE PERMISSION" followed by "REQUESTING PERMISSION". This also happens if you refuse permission.

Comments

  1. Srikanth Sombhatla 2016-01-11

  2. Ricardo Ramirez 2016-01-15

    This is not working using iOS 7
  3. Chee Kiat Ng 2016-01-15

  4. Srikanth Sombhatla 2016-01-15

    [~cng] This has nothing to do with TIMOB-20165. [~rramirez] [~egomez] In iOS7 User cannot request permission explicitly (like in iOS 8). System automatically presents location permission alert when we try to call Ti.Geolocation.getCurrentPosition() or geofencing. This should be updated in our docs. Secondly hasLocationPermissions has a regression issue which is caused because it always operates in iOS 8 mode. This should be fixed.
  5. Srikanth Sombhatla 2016-01-19

    PR https://github.com/appcelerator/titanium_mobile/pull/7639 Changes for iOS 7: 1. Console warning when using Ti.Geolocation.requestLocationPermissions 2. Correctly returns value of Ti.Geolocation.hasLocationPermissions 3. Updated docs accordingly. Alternatively can use the following app.js for testing
       // this sets the background color of the master UIView (when there are no windows/tab groups on it)
       Titanium.UI.setBackgroundColor('#000');
       
       // create base UI tab and root window
       //
       var win = Titanium.UI.createWindow({className:'win1'});
       
       var reqPerm = Titanium.UI.createButton({title: "Request Permission", top: 50});
       reqPerm.addEventListener('click', function(e) {
         checkPermission();
         requestPermission();
       });
       
       var reqLoc = Titanium.UI.createButton({title: "Request Location", top: 150});
       reqLoc.addEventListener('click', function(e) {
         checkPermission();
         getCurrentPosition();
       });
       
       win.add(reqPerm);
       win.add(reqLoc);
       
       function checkPermission(){
         if(Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)){
           Ti.API.info("APP HAS PERMISSION");  
         }else{
           Ti.API.info("APP DOES NOT HAVE PERMISSION");
         }
       }
        
       function requestPermission(){
         Ti.API.info("REQUESTING PERMISSION");
         Ti.Geolocation.requestLocationPermissions(Titanium.Geolocation.AUTHORIZATION_WHEN_IN_USE,function(e){
           Ti.API.info("INSIDE CALLBACK");
           if(e.success){
             Ti.API.info("PERMISSION GRANTED");
           }else{
             Ti.API.info("PERMISSION DENIED");
           }
         });
       }
        
       function checkRequestPermission(){
         checkPermission(requestPermission);
       }
        
       function getCurrentPosition(successHandler,errorHandler){
         Ti.API.info("REQUESTING LOCATION");
         Ti.Geolocation.getCurrentPosition(function(result){
           if (result.error) {
             Ti.API.info("GetCurrentPosition Error");
           }else{
             Ti.API.info("-GetCurrentPosition returned" + JSON.stringify(result));
           }
         });
       }
       
       win.open();
       
  6. Nikita Radaev 2016-01-22

    I disagree that this is the right fix guys. The whole point of using Appcelerator is to abstract away all (or most ) platform-specific conditionals. Besides, same functionality is backwards compatible on Android. I dont understand why it is not possible to do same thing on IOS. SDK should be taking care of addressing this issue and not the users.
  7. Collin Price 2016-01-22

    So instead of making the function backwards compatible, like it is on Android, my code has to check if the user is running iOS and is on iOS 7? I thought the major advantage of using Titanium is that I don't have to think about what platform/OS version the user is running. @ssombhatla Sure iOS 7 doesn't request location permission the same as iOS 8+ but why can't the requestLocationPermissions method do whatever it needs to do to prompt the user on iOS 7?
  8. Srikanth Sombhatla 2016-01-26

    [~CollinPrice], [~nradaev] point taken.
  9. Srikanth Sombhatla 2016-01-26

    Reopening to address community comments.
  10. Srikanth Sombhatla 2016-01-26

    PR: https://github.com/appcelerator/titanium_mobile/pull/7642 Use the same app.js for testing. Reworked to make requestLocationPermissions in iOS7 to behave like iOS8+, where permission alert is presented and continued based on User selection.
  11. Angel Petkov 2016-01-26

    FT and CR approved, thanks Srikanth!
  12. Nikita Radaev 2016-01-28

    Srikanth Sombhatla, yes the issue with Ti.Geolocation.hasLocationPermissions is fixed and it now works as promised, however Ti.Geolocation.requestLocationPermissions() still does not work properly on IOS 7. There is simply no callback being thrown after user GRANTS or DENIES permission untill the app is reloaded. Here is a code snippet to recreate the issue:if(!Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)){ Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE, function(resp){ Ti.API.info("Callback returned = " + JSON.stringify(resp)); if(resp.success){ Ti.API.info("Geolocation permission GRANTED"); }else{ Ti.API.info("Permision denied"); } }); }else{ Ti.API.info("This device has geolocation permissions"); }
  13. Srikanth Sombhatla 2016-01-31

    PR https://github.com/appcelerator/titanium_mobile/pull/7656 This requires that creation of location delegate and subsequent permission alert are presented on main thread. This is because by default JS runs on its own thread enabled by TI_USE_KROLL_THREAD.
  14. Srikanth Sombhatla 2016-02-02

    5_2_X PR: https://github.com/appcelerator/titanium_mobile/pull/7667
  15. Hans Knöchel 2016-02-02

    Approved, thanks!
  16. Harry Bryant 2016-02-02

    Verified as fixed, using an iOS7 device Ti.Geolocation.requestLocationPermissions & Ti.Geolocation.hasLocationPermissions now returns correct value, & Ti.Geolocation.getCurrentPosition() now correctly returns the correct position. Tested on: iPhone 4S (7.1.2) & iPhone 6S (9.2) Devices Mac OSX El Capitan 10.11 (15A284) Appc Studio: 4.5.0.201601262138 Ti SDK: 5.2.0.v20160202103508 Appc NPM: 4.2.3-1 App CLI: 5.2.0-239 Xcode 7.2 Node v4.2.3 *Closing Ticket.*

JSON Source