Search code examples
ioscordovaautostartlocation-services

Starting Cordova iOS app if UIApplicationLaunchOptionsLocationKey is present


I have a Cordova app that records user's trips. It works fine in the background, and I'd like to get it automatically restarted if it's killed for some reason (user swipes it away, phone restarts, etc.).

I'm monitoring a region, and the app partially restarts when the user enters/exits from that. 'Partially' here means the app only runs in the background - Cordova loads my app's plugins, but it never loads the WebView.

For this partial restart, I'm listening for UIApplicationDidFinishLaunchingNotification with UIApplicationLaunchOptionsLocationKey from my plugin's pluginInitialize method and starting location services right away to stay running.

Why doesn't the WebView load? Is there something I need to do to trigger the next stage of initialization when started by iOS?

EDIT 2016/3/7

I did some research and debugging. Apparently, iOS starts my app in the background; here's what I get when auto-started this way vs. a manual start, from the logging line:

        NSLog(@"Launched in: bg:%d active:%d inactive:%d", state == UIApplicationStateBackground, state == UIApplicationStateActive, state == UIApplicationStateInactive);

        Launched in: bg:1 active:0 inactive:0
        Launched in: bg:0 active:0 inactive:1

I verified this code was being reached in both cases (from cordova-ios' v.3.9.2 (Cordova v.5.4.1) CDVViewController:

        NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
        [self.webView loadRequest:appReq];

I see this load finish in the manual case, but not the auto-start case, with the log line:

        Finished load of: file:///var/mobile/Containers/Bundle/Application/[device id]/[app name].app/www/index.html

Why would this load fail when auto-started?


Solution

  • I ended up using an Apple support ticket; their answer is basically "you can't load a web view when started that way":

    If I understand correctly, you are expecting your app to visibly launch to the foreground when you get a location update. that is not how it works at all. Your app will be launched into the background. If you see the UIApplicationLaunchOptionsLocationKey, only your app delegate and the location manager’s delegate class will be initialized. No views will be initialized whatsoever.

    Once an app is launched in the background, it is expected to process the data for a few seconds silently and then yield back to the system. It is not possible to load a web view, or any kind of UI at this stage.

    The only user interaction that would be possible is to schedule a local notification with a message to the user to launch the app. If the user taps the notification, your app will be fully launched.

    Only then you can load your web view.