{ "id": "101928", "key": "TIMOB-11178", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "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": "14162", "description": "Release 3.1.0", "name": "Release 3.1.0", "archived": true, "released": true, "releaseDate": "2013-04-16" }, { "id": "15274", "description": "2013 Sprint 06 API", "name": "2013 Sprint 06 API", "archived": true, "released": true, "releaseDate": "2013-03-25" }, { "id": "14816", "description": "2013 Sprint 06", "name": "2013 Sprint 06", "archived": true, "released": true, "releaseDate": "2013-03-25" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2013-03-18T17:57:49.000+0000", "created": "2012-09-25T10:05:14.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "api", "background", "geolocation", "ios6", "iphone", "qe-testadded" ], "versions": [], "issuelinks": [], "assignee": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2013-10-23T23:15:31.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": "h2. Problem\r\n\r\nIn iOS 6 Apple has made breaking changes to Core Location by implementing the AutoPause API. The AutoPause API pauses the location updates when an application goes into the background and applies to a couple of criteria (i.e. user not moving, no location fix, user discontinues activity). To accurately handle pause events Apple requests to help better predicting whether or not to pause location updates setting an activity type (i.e. navigation, fitness, other). \r\n\r\nThe AutoPause API is enabled by default when an application is compiled against iOS 6.\r\n\r\nThe problem is that at this moment we, Appcelerator Mobile developers, are not able to configure the AutoPause API and updates are always paused when going into the background, even when UIBackgroundModes is set to location and the application is allowed to keep running in the background for longer then 10 minutes. This breaks the working of any tracking or navigation app and renders it useless.\r\n\r\nThe easy fix is to disable the AutoPause API for now by always setting 'pausesLocationUpdatesAutomatically' to NO. Location updates will be send even when the app goes in the background, like it used to work in < iOS 6. Hopefully this could be implemented in the 2.1.3 GA release, so we can resubmit our app to the App Store.\r\n\r\nThe best case scenario is to implement the AutoPause API by adding pausesLocationUpdatesAutomatically and activityType properties (CLLocationManager.h), the CLActivityType constants (CLLocationManager.h) and the pause event listeners (CLLocationManagerDelegate.h) to Ti.Geolocation(.iPhone)\r\n\r\nh2. Test case\r\n\r\nA test application compiled against iOS6 implementing Ti.Geolocation tracking will receive no updates when going into background. Our application did receive a location update every 4 to 5 minutes with horrible accuracy (1000s of meters)\r\n\r\nh2. References\r\n\r\nWWDC 2012 video explaining the AutoPause API: https://developer.apple.com/videos/wwdc/2012/?include=303#303\r\nWWDC 2012 Slides explaining the AutoPause API: http://adcdownload.apple.com//wwdc_2012/wwdc_2012_session_pdfs/session_303__staying_on_track_with_location_services.pdf\r\n\r\nCLLocationManager Class Reference (pausesLocationUpdatesAutomatically and activityType properties): http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html\r\n\r\nCLLocationManagerDelegate protocol reference (pause eventlisteners): http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html", "attachment": [], "flagged": false, "summary": "iOS: Implement iOS6 Core Location AutoPause API", "creator": { "name": "timanrebel", "key": "timanrebel", "displayName": "Timan Rebel", "active": true, "timeZone": "Europe/London" }, "subtasks": [], "reporter": { "name": "timanrebel", "key": "timanrebel", "displayName": "Timan Rebel", "active": true, "timeZone": "Europe/London" }, "environment": "iOS 6", "closedSprints": [ { "id": 3, "state": "closed", "name": "Release 3.0.0", "startDate": "2012-09-27T05:26:46.636Z", "endDate": "2012-10-08T20:05:00.000Z", "completeDate": "2012-12-20T17:03:19.403Z" } ], "comment": { "comments": [ { "id": "222599", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Test case \r\n\r\n{code}\r\n//Global Variables\r\nvar appInBackground = false;\r\n \r\n \r\nvar mainWindow = Titanium.UI.createWindow({ \r\n backgroundColor:Ti.UI.iOS.COLOR_UNDER_PAGE_BACKGROUND\r\n});\r\n \r\nvar label1 = Titanium.UI.createLabel({\r\n color:'#444',\r\n text:'GeoLocation Test \\n----log console----',\r\n font:{fontSize:18,fontFamily:'Helvetica Neue', fontWeight: 'bold'},\r\n textAlign:'center',\r\n width:Ti.UI.FILL,\r\n top: 2\r\n});\r\nmainWindow.add(label1);\r\n \r\nvar label = Ti. UI.createLabel({\r\n top: 50, right:10, left:10,\r\n textAlign: 'left',\r\n width: Ti.UI.SIZE,\r\n height: Ti.UI.SIZE,\r\n text: 'Current Location',\r\n color:'green'\r\n});\r\nvar ta = Ti.UI.createLabel({\r\n top: 70, right:10, left:10,\r\n textAlign: 'left',\r\n width: Ti.UI.SIZE,\r\n height: Ti.UI.SIZE,\r\n text: 'Location update not Received',\r\n color:'red'\r\n});\r\nmainWindow.add(label);\r\nmainWindow.add(ta);\r\nfunction appendTA(txt) {\r\n ta.text = '\\n *********************************** \\n' + txt;\r\n ta.color = \"red\";\r\n setTimeout(function()\r\n {\r\n ta.color = \"green\";\r\n },100);\r\n Ti.API.info('Location Update Received!!');\r\n Ti.API.info('autopause :: ' + Ti.Geolocation.pauseLocationUpdateAutomatically );\r\n Ti.API.info(txt);\r\n}\r\n \r\nvar locationAdded = false; //Global Variable\r\n \r\nTi.Geolocation.purpose = \"GPS demo\";\r\n \r\nfunction translateErrorCode(code) {\r\n if (code == null) {\r\n return null;\r\n }\r\n switch (code) {\r\n case Ti.Geolocation.ERROR_LOCATION_UNKNOWN:\r\n return \"Location unknown\";\r\n case Ti.Geolocation.ERROR_DENIED:\r\n return \"Access denied\";\r\n case Ti.Geolocation.ERROR_NETWORK:\r\n return \"Network error\";\r\n case Ti.Geolocation.ERROR_HEADING_FAILURE:\r\n return \"Failure to detect heading\";\r\n case Ti.Geolocation.ERROR_REGION_MONITORING_DENIED:\r\n return \"Region monitoring access denied\";\r\n case Ti.Geolocation.ERROR_REGION_MONITORING_FAILURE:\r\n return \"Region monitoring access failure\";\r\n case Ti.Geolocation.ERROR_REGION_MONITORING_DELAYED:\r\n return \"Region monitoring setup delayed\";\r\n }\r\n}\r\n \r\nif (Titanium.Geolocation.locationServicesEnabled === false)\r\n{\r\n Titanium.UI.createAlertDialog({title:'Kitchen Sink', message:'Your device has geo turned off - turn it on.'}).show();\r\n}\r\nelse\r\n{\r\n var authorization = Titanium.Geolocation.locationServicesAuthorization;\r\n Ti.API.info('Authorization: '+authorization);\r\n if (authorization == Titanium.Geolocation.AUTHORIZATION_DENIED) {\r\n Ti.UI.createAlertDialog({\r\n title:Titanium.App.getName(),\r\n message:'You have disallowed Titanium from running geolocation services.'\r\n }).show();\r\n }\r\n else if (authorization == Titanium.Geolocation.AUTHORIZATION_RESTRICTED) {\r\n Ti.UI.createAlertDialog({\r\n title:Titanium.App.getName(),\r\n message:'Your system has disallowed Titanium from running geolocation services.'\r\n }).show();\r\n } else {\r\n \r\n //\r\n // SET ACCURACY - THE FOLLOWING VALUES ARE SUPPORTED\r\n \r\n /***********************************************************************************\r\n POSSIBLE VALUES\r\n Titanium.Geolocation.ACCURACY_BEST\r\n Titanium.Geolocation.ACCURACY_NEAREST_TEN_METERS\r\n Titanium.Geolocation.ACCURACY_HUNDRED_METERS\r\n Titanium.Geolocation.ACCURACY_KILOMETER\r\n Titanium.Geolocation.ACCURACY_THREE_KILOMETERS\r\n Titanium.Geolocation.ACCURACY_BEST_FOR_NAVIGATION // NEWLY ADDED\r\n ************************************************************************************/\r\n \r\n Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_THREE_KILOMETERS;\r\n \r\n //\r\n // SET DISTANCE FILTER. THIS DICTATES HOW OFTEN AN EVENT FIRES BASED ON THE DISTANCE THE DEVICE MOVES\r\n // THIS VALUE IS IN METERS\r\n //\r\n \r\n Titanium.Geolocation.distanceFilter = 0.1;\r\n \r\n \r\n /************************************************************************************\r\n Titanium.Geolocation.ACTIVITYTYPE_OTHER;// default\r\n Titanium.Geolocation.ACTIVITYTYPE_AUTOMOTIVE_NAVIGATION;\r\n Titanium.Geolocation.ACTIVITYTYPE_FITNESS;// \r\n Titanium.Geolocation.ACTIVITYTYPE_OTHER_NAVIGATION;// \r\n ************************************************************************************/\r\n \r\n \r\n Titanium.Geolocation.activityType =Titanium.Geolocation.ACTIVITYTYPE_FITNESS;\r\n Titanium.Geolocation.pauseLocationUpdateAutomatically = false;//change switch value(s1) also\r\n \r\n Titanium.Geolocation.addEventListener('locationupdatepaused',function(){\r\n Ti.API.info('Geolocation location updates Paused!!**********************');\r\n var notification = Ti.App.iOS.scheduleLocalNotification({\r\n alertBody:\"Location Update Paused !!!\",\r\n alertAction:\"Resume ?\",\r\n });\r\n });\r\n \r\n Titanium.Geolocation.addEventListener('locationupdateresumed',function(){\r\n Ti.API.info('********************Geolocation location updates Resumed!!**********************');\r\n var notification = Ti.App.iOS.scheduleLocalNotification({\r\n alertBody:\"Location Update Resumed !!!\",\r\n alertAction:\"Resume ?\",\r\n });\r\n });\r\n \r\n \r\n var l1 = Ti.UI.createLabel({\r\n text:'pauseLocationUpdatesAutomatically?:',\r\n font:{fontSize:12},\r\n bottom:2,\r\n left:0\r\n });\r\n var s1 = Ti.UI.createSwitch({\r\n value:false,\r\n right:10,\r\n bottom:2,\r\n });\r\n s1.addEventListener('change', function() {\r\n if (s1.value) {\r\n Titanium.Geolocation.pauseLocationUpdateAutomatically = true;\r\n }\r\n else {\r\n Titanium.Geolocation.pauseLocationUpdateAutomatically = false;\r\n }\r\n });\r\n \r\n mainWindow.add(l1);\r\n mainWindow.add(s1);\r\n }\r\n \r\n \r\n} \r\nvar logLocation = function(e)\r\n{\r\n Ti.Media.vibrate();\r\n if (!e.success || e.error)\r\n { \r\n appendTA('error:' + JSON.stringify(e.error));\r\n Ti.API.info(\"Code translation: \"+translateErrorCode(e.code));\r\n return;\r\n }\r\n var longitude = e.coords.longitude;\r\n var latitude = e.coords.latitude;\r\n var altitude = e.coords.altitude;\r\n var heading = e.coords.heading;\r\n var accuracy = e.coords.accuracy;\r\n var speed = e.coords.speed;\r\n var timestamp = e.coords.timestamp;\r\n var altitudeAccuracy = e.coords.altitudeAccuracy; \r\n \r\n var logMessage = 'Location Update \\n (lat: ' + latitude+ ', long:' + longitude +') \\n accuracy:' + accuracy +' \\n timestamp:' +new Date(timestamp); \r\n \r\n appendTA(logMessage);\r\n if(appInBackground){\r\n Ti.API.info('APP is in background going to fire event');\r\n var notification = Ti.App.iOS.scheduleLocalNotification({\r\n alertBody:\"Location Update from background received \\n\" +logMessage,\r\n alertAction:\"Re-Launch!\",\r\n date:new Date(new Date().getTime() ) \r\n });\r\n }\r\n \r\n} \r\n \r\n \r\nmainWindow.addEventListener('close', function(e) {\r\n Ti.API.info(\"Window closed !! \");\r\n if (locationAdded) {\r\n Ti.API.info(\"removing location callback on destroy\");\r\n Titanium.Geolocation.removeEventListener('location', logLocation);\r\n locationAdded = false;\r\n }\r\n});\r\n \r\nmainWindow.addEventListener('open', function(e) {\r\n Ti.API.info(\"Window opened !!\");\r\n \r\n if (!locationAdded && logLocation) {\r\n Ti.API.info(\"adding location callback on resume\");\r\n Titanium.Geolocation.addEventListener('location', logLocation);\r\n locationAdded = true;\r\n }\r\n});\r\n \r\nTitanium.Geolocation.addEventListener('locationupdatepaused', function(){\r\n Ti.API.info('location manager paused!!');\r\n});\r\nTitanium.Geolocation.addEventListener('locationupdateresumed', function(){\r\n Ti.API.info('location manager resumed!!');\r\n});\r\n \r\n \r\nTi.App.addEventListener('resumed',function(e){\r\n appInBackground = false;\r\n Ti.API.info(\"app has resumed from the background\");\r\n});\r\n \r\nTi.App.addEventListener('pause',function(e){\r\n Ti.API.info(\"app was paused from the foreground\");\r\n appInBackground = true;\r\n});\r\n \r\nTi.App.addEventListener('resume',function(e){\r\n appInBackground = false;\r\n Ti.API.info(\"app has resumed from the background\");\r\n});\r\n \r\nTi.App.addEventListener('paused',function(e){\r\n Ti.API.info(\"app was paused from the foreground\");\r\n appInBackground = true;\r\n});\r\n \r\nmainWindow.open(); \r\n{code}", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-10-08T21:28:11.000+0000", "updated": "2013-03-18T17:16:26.000+0000" }, { "id": "224799", "author": { "name": "timanrebel", "key": "timanrebel", "displayName": "Timan Rebel", "active": true, "timeZone": "Europe/London" }, "body": "Any progress? We currently have a non working app in the app store, which we can't update because we're waiting on this fix.\r\n\r\nWhat is necessary to properly test this feature and what can we do to help?", "updateAuthor": { "name": "timanrebel", "key": "timanrebel", "displayName": "Timan Rebel", "active": true, "timeZone": "Europe/London" }, "created": "2012-10-24T14:42:18.000+0000", "updated": "2012-10-24T14:42:18.000+0000" }, { "id": "229731", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Will revisit the ticket after 6.1.0 is out officially", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-12-04T00:17:48.000+0000", "updated": "2012-12-04T00:17:48.000+0000" }, { "id": "242080", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-13T21:14:32.000+0000", "updated": "2013-03-14T18:53:53.000+0000" }, { "id": "242081", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "New PR is up https://github.com/appcelerator/titanium_mobile/pull/3963", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-13T21:15:40.000+0000", "updated": "2013-03-13T21:15:40.000+0000" }, { "id": "243304", "author": { "name": "oromero", "key": "oromero", "displayName": "Olga Romero", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Tested and verified fix with:\nTitanium Studio, build: 3.1.0.201303182358\nTitanium SDK, build: 3.1.0.v20130319225749\nXCode 4.6\nDevice: iPhone5 iOS 6.1.2\n\nFollowing Testing instructions, results as expected.", "updateAuthor": { "name": "oromero", "key": "oromero", "displayName": "Olga Romero", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-20T23:51:32.000+0000", "updated": "2013-03-20T23:51:32.000+0000" } ], "maxResults": 6, "total": 6, "startAt": 0 } } }