Project: titanium
Issue TIMOB-20004: iOS: Differences between new permission request responses
While working in the [5.1 sample|https://github.com/appcelerator-developer-relations/appc-sample-ti510] I noticed some differences between the responses of the new permission request methods. I created a separate test case to show the differences so we can address them in a next release. Nothing big, except for the first bullet maybe. * Unlike the others, the callback for {{requestLocationPermissions()}} is only called the first time. You have to force close and then re-open the app for it to work again. * The response for {{requestLocationPermissions}} also has {{authorizationStatus}}, which would be very useful to have in the response for the others as well. * On success, the response for {{requestLocationPermissions}} has an empty string for {{error}} where it should either have a message or be undefined. * When unknown, {{requestContactsPermissions}} has a not very helpful _Access Denied_ {{error}} instead of just being undefined like {{Calendar}} and {{Camera}}. * Unless permission was granted, the {{error}} for {{requestLocationPermissions}} is always _The user is unable to allow access to location._, which is not very helpful or even misleading since the user is perfectly able, he just denied permission to the app. Calendar and Contacts have better error messages. * When denied, the response for {{requestCameraPermissions}} has no {{error}} like the others. * I have no idea where {{code}} comes from but if I deny it (probably by coincidence) correctly maps to {{AUTHORIZATION_DENIED}} for Calendar and Contacts. Would be helpful to have the meaning of this code documented. * In iOS 8, denying contacts permission sends success response to callback. h2. Sample Don't forget to add {{NSLocationAlwaysUsageDescriptionDeny or grant permission to test different scenarios.}} to {{tiapp.xml}}. {code:javascript} var win = Ti.UI.createWindow({	backgroundColor: 'white' }); var btn = Ti.UI.createButton({	title: 'Request Permissions' }); btn.addEventListener('click', function(e) {	console.log('\n--------------------------------------------------------\n');	var Calendar = {};	Calendar[Ti.Calendar.AUTHORIZATION_AUTHORIZED] = 'AUTHORIZATION_AUTHORIZED';	Calendar[Ti.Calendar.AUTHORIZATION_DENIED] = 'AUTHORIZATION_DENIED';	Calendar[Ti.Calendar.AUTHORIZATION_RESTRICTED] = 'AUTHORIZATION_RESTRICTED';	Calendar[Ti.Calendar.AUTHORIZATION_UNKNOWN] = 'AUTHORIZATION_UNKNOWN';	console.log('Ti.Calendar.hasCalendarPermissions ' + Ti.Calendar.hasCalendarPermissions());	console.log('Ti.Calendar.eventsAuthorization Ti.Calendar.' + Calendar[Ti.Calendar.eventsAuthorization] + '\n');	var Contacts = {};	Contacts[Ti.Contacts.AUTHORIZATION_AUTHORIZED] = 'AUTHORIZATION_AUTHORIZED';	Contacts[Ti.Contacts.AUTHORIZATION_DENIED] = 'AUTHORIZATION_DENIED';	Contacts[Ti.Contacts.AUTHORIZATION_RESTRICTED] = 'AUTHORIZATION_RESTRICTED';	Contacts[Ti.Contacts.AUTHORIZATION_UNKNOWN] = 'AUTHORIZATION_UNKNOWN';	console.log('Ti.Contacts.hasContactsPermissions ' + Ti.Contacts.hasContactsPermissions());	console.log('Ti.Contacts.contactsAuthorization Ti.Contacts.' + Contacts[Ti.Contacts.contactsAuthorization] + '\n');	var Geolocation = {};	Geolocation[Ti.Geolocation.AUTHORIZATION_AUTHORIZED] = 'AUTHORIZATION_AUTHORIZED';	Geolocation[Ti.Geolocation.AUTHORIZATION_DENIED] = 'AUTHORIZATION_DENIED';	Geolocation[Ti.Geolocation.AUTHORIZATION_RESTRICTED] = 'AUTHORIZATION_RESTRICTED';	Geolocation[Ti.Geolocation.AUTHORIZATION_UNKNOWN] = 'AUTHORIZATION_UNKNOWN';	Geolocation[Ti.Geolocation.AUTHORIZATION_ALWAYS] = 'AUTHORIZATION_ALWAYS';	Geolocation[Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE] = 'AUTHORIZATION_WHEN_IN_USE';	console.log('Ti.Geolocation.hasLocationPermissions ' + Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS));	console.log('Ti.Geolocation.locationServicesAuthorization Ti.Geolocation.' + Geolocation[Ti.Geolocation.locationServicesAuthorization] + '\n');	var Media = {};	Media[Ti.Media.CAMERA_AUTHORIZATION_AUTHORIZED] = 'CAMERA_AUTHORIZATION_AUTHORIZED';	Media[Ti.Media.CAMERA_AUTHORIZATION_DENIED] = 'CAMERA_AUTHORIZATION_DENIED';	Media[Ti.Media.CAMERA_AUTHORIZATION_RESTRICTED] = 'CAMERA_AUTHORIZATION_RESTRICTED';	Media[Ti.Media.CAMERA_AUTHORIZATION_NOT_DETERMINED] = 'CAMERA_AUTHORIZATION_NOT_DETERMINED';	console.log('Ti.Media.hasCameraPermissions ' + Ti.Media.hasCameraPermissions());	console.log('Ti.Media.cameraAuthorizationStatus Ti.Media.' + Media[Ti.Media.cameraAuthorizationStatus] + '\n');	console.log('--------------------------------------------------------\n');	Ti.Calendar.requestCalendarPermissions(function(e) {	console.log('Ti.Calendar.requestCalendarPermissions ' + JSON.stringify(e, null, 2));	console.log('Ti.Calendar.requestCalendarPermissions:code (mapped) ' + Calendar[e.code] + '\n');	});	Ti.Contacts.requestContactsPermissions(function(e) {	console.log('Ti.Contacts.requestContactsPermissions ' + JSON.stringify(e, null, 2));	console.log('Ti.Contacts.requestContactsPermissions:code (mapped) ' + Contacts[e.code] + '\n');	});	Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, function(e) {	console.log('Ti.Geolocation.requestLocationPermissions ' + JSON.stringify(e, null, 2));	console.log('Ti.Geolocation.requestLocationPermissions:code (mapped) ' + Geolocation[e.code]);	console.log('Ti.Geolocation.requestLocationPermissions:authorizationStatus ' + Geolocation[e.authorizationStatus] + '\n');	});	Ti.Media.requestCameraPermissions(function(e) {	console.log('Ti.Media.requestCameraPermissions ' + JSON.stringify(e, null, 2));	console.log('Ti.Media.requestCameraPermissions:code (mapped) ' + Media[e.code] + '\n');	}); }); win.add(btn); win.open(); {code} h2. Logs h3. Scenario: Deny All {code} [INFO] Ti.Calendar.hasCalendarPermissions false [INFO] Ti.Calendar.eventsAuthorization Ti.Calendar.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Contacts.hasContactsPermissions false [INFO] Ti.Contacts.contactsAuthorization Ti.Contacts.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Geolocation.hasLocationPermissions false [INFO] Ti.Geolocation.locationServicesAuthorization Ti.Geolocation.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Media.hasCameraPermissions false [INFO] Ti.Media.cameraAuthorizationStatus Ti.Media.CAMERA_AUTHORIZATION_NOT_DETERMINED [INFO] [INFO] Ti.Calendar.requestCalendarPermissions { [INFO] "success": false, [INFO] "code": 1 [INFO] } [INFO] Ti.Calendar.requestCalendarPermissions:code (mapped) AUTHORIZATION_RESTRICTED [INFO] [INFO] Ti.Contacts.requestContactsPermissions { [INFO] "success": false, [INFO] "error": "Access Denied", [INFO] "code": 100 [INFO] } [INFO] Ti.Contacts.requestContactsPermissions:code (mapped) undefined [INFO] [INFO] Ti.Media.requestCameraPermissions { [INFO] "success": false, [INFO] "code": 1 [INFO] } [INFO] Ti.Media.requestCameraPermissions:code (mapped) CAMERA_AUTHORIZATION_RESTRICTED {code} Because of TIMOB-20002 I use the Ti 5.1 Sample App to read the Geolocation callback: {code} [INFO] Ti.Geolocation.requestLocationPermissions { [INFO] "success": false, [INFO] "code": 1, [INFO] "authorizationStatus": 2, [INFO] "error": "The user is unable to allow access to location." [INFO] } [INFO] Ti.Geolocation.requestLocationPermissions.code (mapped) Ti.Geolocation.AUTHORIZATION_RESTRICTED [INFO] Ti.Geolocation.requestLocationPermissions.authorizationStatus (mapped) Ti.Geolocation.AUTHORIZATION_DENIED {code} h3. Scenario: Denied Before {code} [INFO] Ti.Calendar.hasCalendarPermissions false [INFO] Ti.Calendar.eventsAuthorization Ti.Calendar.AUTHORIZATION_DENIED [INFO] [INFO] Ti.Contacts.hasContactsPermissions false [INFO] Ti.Contacts.contactsAuthorization Ti.Contacts.AUTHORIZATION_DENIED [INFO] [INFO] Ti.Geolocation.hasLocationPermissions false [INFO] Ti.Geolocation.locationServicesAuthorization Ti.Geolocation.AUTHORIZATION_DENIED [INFO] [INFO] Ti.Media.hasCameraPermissions false [INFO] Ti.Media.cameraAuthorizationStatus Ti.Media.CAMERA_AUTHORIZATION_DENIED [INFO] [INFO] -------------------------------------------------------- [INFO] [INFO] Ti.Calendar.requestCalendarPermissions { [INFO] "success": false, [INFO] "error": "The user has denied access to events in Calendar.", [INFO] "code": 2 [INFO] } [INFO] Ti.Calendar.requestCalendarPermissions:code (mapped) AUTHORIZATION_DENIED [INFO] [INFO] Ti.Contacts.requestContactsPermissions { [INFO] "success": false, [INFO] "error": "The user has denied access to the address book", [INFO] "code": 2 [INFO] } [INFO] Ti.Contacts.requestContactsPermissions:code (mapped) AUTHORIZATION_DENIED [INFO] [INFO] Ti.Media.requestCameraPermissions { [INFO] "success": false, [INFO] "code": 1 [INFO] } [INFO] Ti.Media.requestCameraPermissions:code (mapped) CAMERA_AUTHORIZATION_RESTRICTED {code} Because of TIMOB-20002 I use the Ti 5.1 Sample App to read the Geolocation callback: {code} [INFO] Ti.Geolocation.requestLocationPermissions { [INFO] "success": false, [INFO] "code": 1, [INFO] "authorizationStatus": 2, [INFO] "error": "The user is unable to allow access to location." [INFO] } [INFO] Ti.Geolocation.requestLocationPermissions.code (mapped) Ti.Geolocation.AUTHORIZATION_RESTRICTED [INFO] Ti.Geolocation.requestLocationPermissions.authorizationStatus (mapped) Ti.Geolocation.AUTHORIZATION_DENIED {code} h3. Scenario: Allow All {code} [INFO] Ti.Calendar.hasCalendarPermissions false [INFO] Ti.Calendar.eventsAuthorization Ti.Calendar.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Contacts.hasContactsPermissions false [INFO] Ti.Contacts.contactsAuthorization Ti.Contacts.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Geolocation.hasLocationPermissions false [INFO] Ti.Geolocation.locationServicesAuthorization Ti.Geolocation.AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Media.hasCameraPermissions false [INFO] Ti.Media.cameraAuthorizationStatus Ti.Media.CAMERA_AUTHORIZATION_NOT_DETERMINED [INFO] [INFO] -------------------------------------------------------- [INFO] [INFO] Ti.Calendar.requestCalendarPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Calendar.requestCalendarPermissions:code (mapped) AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Contacts.requestContactsPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Contacts.requestContactsPermissions:code (mapped) AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Media.requestCameraPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Media.requestCameraPermissions:code (mapped) CAMERA_AUTHORIZATION_NOT_DETERMINED {code} Because of TIMOB-20002 I use the Ti 5.1 Sample App to read the Geolocation callback: {code} [INFO] Ti.Geolocation.requestLocationPermissions { [INFO] "success": true, [INFO] "code": 0, [INFO] "authorizationStatus": 3, [INFO] "error": "" [INFO] } [INFO] Ti.Geolocation.requestLocationPermissions.code (mapped) Ti.Geolocation.AUTHORIZATION_UNKNOWN [INFO] Ti.Geolocation.requestLocationPermissions.authorizationStatus (mapped) Ti.Geolocation.AUTHORIZATION_AUTHORIZED {code} h3. Scenario: Allowed All Before {code} [INFO] Ti.Calendar.hasCalendarPermissions true [INFO] Ti.Calendar.eventsAuthorization Ti.Calendar.AUTHORIZATION_AUTHORIZED [INFO] [INFO] Ti.Contacts.hasContactsPermissions true [INFO] Ti.Contacts.contactsAuthorization Ti.Contacts.AUTHORIZATION_AUTHORIZED [INFO] [INFO] Ti.Geolocation.hasLocationPermissions true [INFO] Ti.Geolocation.locationServicesAuthorization Ti.Geolocation.AUTHORIZATION_ALWAYS [INFO] [INFO] Ti.Media.hasCameraPermissions true [INFO] Ti.Media.cameraAuthorizationStatus Ti.Media.CAMERA_AUTHORIZATION_AUTHORIZED [INFO] [INFO] -------------------------------------------------------- [INFO] [INFO] Ti.Calendar.requestCalendarPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Calendar.requestCalendarPermissions:code (mapped) AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Contacts.requestContactsPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Contacts.requestContactsPermissions:code (mapped) AUTHORIZATION_UNKNOWN [INFO] [INFO] Ti.Media.requestCameraPermissions { [INFO] "success": true, [INFO] "code": 0 [INFO] } [INFO] Ti.Media.requestCameraPermissions:code (mapped) CAMERA_AUTHORIZATION_NOT_DETERMINED {code} Because of TIMOB-20002 I use the Ti 5.1 Sample App to read the Geolocation callback: {code} [INFO] Ti.Geolocation.requestLocationPermissions { [INFO] "success": true, [INFO] "code": 0, [INFO] "authorizationStatus": 3, [INFO] "error": "" [INFO] } [INFO] Ti.Geolocation.requestLocationPermissions.code (mapped) Ti.Geolocation.AUTHORIZATION_UNKNOWN [INFO] Ti.Geolocation.requestLocationPermissions.authorizationStatus (mapped) Ti.Geolocation.AUTHORIZATION_AUTHORIZED {code}
Story points: 3