Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25858] iOS: Question on how to use "trackSignificantLocationChange" with background location update

GitHub Issuen/a
TypeStory
PriorityNone
StatusResolved
ResolutionNeeds more info
Resolution Date2018-07-26T21:54:08.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsiOS
Labelsgeolocation, ios
ReporterMostafizur Rahman
AssigneeHans Knöchel
Created2018-03-12T18:50:26.000+0000
Updated2018-07-26T21:54:08.000+0000

Description

Hello, On iOS, when using Ti.Geolocation.trackSignificantLocationChange and dealing with background updates with args.launchOptionsLocationKey we are seeing an issue where after a background update has come in while the app was closed and the next launch of the app hangs on the splash screen. The app must be manually closed in order to get farther than the splash screen. *Example Code:* Example app attached. *To reproduce:* 1. Install app on physical device and choose "Always" allow location permission. 2. Force close app with the test switcher 3. Move device until you get a background location update 4. Launch the app and observe the app hang on the launch screen

Attachments

FileDateSize
test-background-location.zip2018-03-12T18:46:37.000+00005546906

Comments

  1. Hans Knöchel 2018-03-13

    I highly suspect that the app crashes because the launch-keys contain a key that is not bridged so far. This would be indicated by having this issue on specific iOS-versions. I will update the ticket with my findings. *EDIT*: I am having a hard time trying to trigger the significant location without going on a train ride now. I'll try some more, but hints on how that was tested on your side would be appreciated!
  2. Hans Knöchel 2018-03-13

    Okay, here is the issue: You are checking for the location-based launch in the following snippet:
       if (isiOS()) {
           var args = Ti.App.getArguments();
           if (args.launchOptionsLocationKey) {
               Ti.API.info ("[APP] launched on location update");
               Ti.App.Properties.setBool('loc_updated', true);
           }
           else {
               start_app();
           }
       }
       else {
           start_app();
       }
       
    If the app is Android, you skip the location-handling and just launch it. But for iOS, if the app is opened by the location update (2nd nested if-statement), you only set the Ti.App.Properties flag but don't actually finish launching. Now when opening the app (in a time where the app was not auto-killed by iOS due to background inactivity), the launch was already booted, but the window wasn't opened, resulting in exactly this behavior (the displayed splash screen). I would propose that you simply do the same app-setup (opening the app / root window) and it will be fixed. In addition, I would recommend to clean up the "location" event-listener when closing the app, as it may be added twice if not (although not tested so far). Here is my (working) test-case (that also simplifies the if-statements):
       function start_app() {
         var launched = Ti.App.Properties.getBool('loc_updated', false);
       
         if (launched) {
           Ti.API.warn("app launched in background");
         }
       
         var win = Ti.UI.createWindow({
           backgroundColor: '#fff'
         });
       
         win.addEventListener('open', function() {
           if (Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS)) {
             Titanium.Geolocation.addEventListener('location', locationCallback);
           } else {
             requestLocationPermissions();
           }
         });
         win.addEventListener('close', function() {
           if (!Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS)) {
             return;
           }
           Titanium.Geolocation.removeEventListener('location', locationCallback);
         });
         win.add(Ti.UI.createLabel({
           text: 'Hello World!'
         }));
         win.open();
       }
       
       function isiOS() {
         return Ti.Platform.name === 'iOS' || Ti.Platform.name === 'iPhone OS';
       }
       
       function requestLocationPermissions() {
         Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, function(e) {
           Ti.Geolocation.trackSignificantLocationChange = true;
           Titanium.Geolocation.addEventListener('location', locationCallback);
         });
       }
       
       function locationCallback(e) {
         Ti.API.info("[app] got location update");
       }
       
       if (isiOS()) {
         var args = Ti.App.getArguments();
         if (args.launchOptionsLocationKey) {
           Ti.API.info("[APP] launched on location update");
           Ti.App.Properties.setBool('loc_updated', true);
         }
       }
       
       start_app();
       
    Let me know if this is working for you!
  3. Hans Knöchel 2018-03-14

    I've updated the JIRA ticket to reflect this to be a Story instead of a Bug as it's the same behavior as natively.

JSON Source