{ "id": "169840", "key": "TIMOB-25322", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "19906", "description": "", "name": "Release 6.3.0", "archived": false, "released": true, "releaseDate": "2017-11-01" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2017-10-27T18:40:43.000+0000", "created": "2017-09-20T10:37:29.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2017-10-31T03:42:06.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "h1. Context\r\n\r\nSince iOS 11 the location permission model is more strict. Developers are not allowed to support \"Always\" only anymore. Apple advices a 2 step approach to ask users for the \"Always\" support as explained in this blogpost:\r\nhttps://m.rover.io/wwdc-2017-update-significant-updates-to-location-permissions-coming-with-ios-11-41f96001f87f\r\n\r\nThe current geolocation module doesn't support this strategy though due to this check: https://github.com/appcelerator/titanium_mobile/blob/822b2eeca1af07d6405ec47e5a33568b12362939/iphone/Classes/GeolocationModule.m#L816\r\n\r\nBecause of this, you won't be able to support the advised approach to require users to authorise the 'Always' mode which is needed to support geofences and beacon technology.\r\n\r\nRead more [here|https://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services/request_always_authorization]. \r\n\r\nEdit by Hans: In addition, there is another new constant called {{NSPhotoLibraryAddUsageDescription}} that is now required when attempting to write to the photo-gallery. It works without this change, but this change will warn the user if it's not set to track down the changes more easily.\r\n\r\nP.S.: (by Hans): Apple made a typo in the above article. It is {{NSLocationAlwaysAndWhenInUseUsageDescription}}, not {{NSLocationAlwaysAndWhenInUsageDescription}}. I filed a radar for Apple regarding that.", "attachment": [], "flagged": false, "summary": "iOS: Geolocation should be able to handle iOS 11 permission upgrade, Media should warn when writing to gallery", "creator": { "name": "jvandijk", "key": "jvandijk", "displayName": "Jeroen van Dijk", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "jvandijk", "key": "jvandijk", "displayName": "Jeroen van Dijk", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": null, "comment": { "comments": [ { "id": "428157", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/9458\r\nPR (6_3_X): (Awaiting initial fix to be accepted)\r\n\r\n*Test-Case*:\r\n# Add the NSLocationAlwaysAndWhenInUseUsageDescription to your plist and ensure location services (GPS) are turned on\r\n# Click the first button. It should display the options \"When In Use\" or \"Never\"\r\n# Click the second button (to request \"Always\" permissions). It should display both options (When in Use + Always), select \"Always\"\r\n# Click the third button. It should log the current location and no warning\r\n# Reset the simulator and try to hit the third button without granting any permissions. It should work but throw a warning in the logs, telling you to request permissions beforehand when using iOS 11 and later.\r\n\r\n*Code*:\r\n{code:js}\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: '#fff',\r\n layout: 'vertical'\r\n});\r\n \r\nvar btn1 = Ti.UI.createButton({\r\n title: '1. Request \"When In Use\" authorization',\r\n top: 50\r\n});\r\n \r\nbtn1.addEventListener('click', function() {\r\n if (Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)) {\r\n Ti.API.info('Success (has \"when in use\" already)');\r\n return;\r\n }\r\n\r\n Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE, function(e) {\r\n Ti.API.info('Success (when in use): ' + e.success);\r\n if (!e.success) {\r\n Ti.API.error('Error (when in use): ' + e.error);\r\n }\r\n });\r\n});\r\n \r\nvar btn2 = Ti.UI.createButton({\r\n title: '2. Upgrade to \"Always\" authorization',\r\n top: 50\r\n});\r\n \r\nbtn2.addEventListener('click', function() {\r\n if (Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS)) {\r\n Ti.API.info('Success (has \"always\" already)');\r\n return;\r\n }\r\n Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, function(e) {\r\n Ti.API.info('Success (always): ' + e.success);\r\n if (!e.success) {\r\n Ti.API.error('Error (always): ' + e.error);\r\n }\r\n });\r\n});\r\n \r\nvar btn3 = Ti.UI.createButton({\r\n title: '3. Use Ti.Geolocation API\\'s',\r\n top: 50\r\n});\r\n \r\nbtn3.addEventListener('click', function() {\r\n \r\n if (!Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS) && !Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)) {\r\n Ti.API.warn('Prepare: Probably will warn on iOS 11 (only) because trying to access Ti.Geolocation API\\'s without authorizing before');\r\n }\r\n \r\n Ti.Geolocation.getCurrentPosition(function(e) {\r\n Ti.API.info(e);\r\n });\r\n});\r\n \r\nwin.add(btn1);\r\nwin.add(btn2);\r\nwin.add(btn3);\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-09-20T13:20:19.000+0000", "updated": "2017-10-20T11:00:28.000+0000" }, { "id": "428816", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~hknoechel] can you add test case for using \"NSPhotoLibraryAddUsageDescription\" key and back port for 6_3_X? Thanks!", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2017-10-09T09:40:46.000+0000", "updated": "2017-10-09T09:40:46.000+0000" }, { "id": "428878", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Test Case (Using NSPhotoLibraryAddUsageDescription) - \r\n\r\nDo not add 'NSPhotoLibraryAddUsageDescription' in tiapp.xml. It should log error message.\r\nIf added no error log.\r\n \r\n{code:java}\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: \"#fff\"\r\n});\r\n \r\nvar btn = Ti.UI.createButton({\r\n title: \"Open Camera\",\r\n top: 50\r\n});\r\nbtn.addEventListener(\"click\", function() {\r\n Ti.Media.showCamera({\r\n showControls: true,\r\n success: function(e) {\r\n Ti.Media.hideCamera();\r\n },\r\n saveToPhotoGallery: true,\r\n mediaTypes: Ti.Media.MEDIA_TYPE_PHOTO\r\n });\r\n});\r\n \r\nwin.add(btn);\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2017-10-10T06:18:06.000+0000", "updated": "2017-10-10T06:18:06.000+0000" }, { "id": "428887", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Backport (6_3_X): https://github.com/appcelerator/titanium_mobile/pull/9514\r\n\r\nAnother test-case for the {{saveToGallery}} changes:\r\n{code:js}\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: \"#fff\"\r\n});\r\n \r\nvar btn = Ti.UI.createButton({\r\n title: \"Save to Gallery\",\r\n top: 50\r\n});\r\nbtn.addEventListener(\"click\", function() {\r\n var view = Ti.UI.createView({\r\n width: 1000,\r\n height: 1000,\r\n backgroundColor: 'red'\r\n });\r\n \r\n Ti.Media.saveToPhotoGallery(view.toImage(), {\r\n success: function(e) {\r\n if (!e.success) {\r\n Ti.API.error('Error saving file! Error: ' + e.error);\r\n return;\r\n }\r\n Ti.API.error('Successfully saved file!');\r\n },\r\n error: function(e) {\r\n Ti.API.error('Error saving file! Error: ' + e.error);\r\n }\r\n })\r\n});\r\n \r\nwin.add(btn);\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-10-10T08:09:19.000+0000", "updated": "2017-10-10T08:16:02.000+0000" }, { "id": "429288", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Reopening ticket to include additional changes now being more clear. Here is what's exactly going on when targeting iOS 11:\r\n# You *always* need to include the {{NSLocationWhenInUseUsageDescription}} key, whether or not you don't plan to use when-in-use permissions. This is a constraint added by Apple to avoid crawling geolocation-data.\r\n# If you wan to have the \"when-in-use\" permissions, you still only need the {{NSLocationWhenInUseUsageDescription}} key covered above\r\n# If you want to have the \"always\" permissions, you need all three keys:\r\n* NSLocationWhenInUseUsageDescription\r\n* NSLocationAlwaysUsageDescription\r\n* NSLocationAlwaysAndWhenInUseUsageDescription\r\n# If you are missing required keys, Titanium will now throw very descriptive error-logs to ensure you don't miss anything\r\n\r\nPR to implement those improvements coming later today.\r\n", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-10-19T12:55:17.000+0000", "updated": "2017-10-19T12:55:17.000+0000" }, { "id": "429289", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/9537\r\nPR (6_3_X): https://github.com/appcelerator/titanium_mobile/pull/9538", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-10-19T13:10:27.000+0000", "updated": "2017-10-19T13:10:27.000+0000" }, { "id": "429875", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "FR Passed. The WhenInUse key is always required. To have \"always\" permissions, both Always and AlwaysAndWhenInUse keys are required. Appropriate error messages appear if the required keys are not present.", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-10-31T03:37:31.000+0000", "updated": "2017-10-31T03:37:31.000+0000" }, { "id": "429876", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified in SDK builds 6.3.0.v20171030181741 & 7.0.0.v20171030085253", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-10-31T03:42:06.000+0000", "updated": "2017-10-31T03:42:06.000+0000" } ], "maxResults": 8, "total": 8, "startAt": 0 } } }