Search code examples
iosswiftcore-locationappdelegatecbcentralmanager

iOS Swift application instance time alive


I have created an application that uses location services and bluetooth services. Inside AppDelegate using significant location changes I am assigning a new instance of CBCentralManager like this:

class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate,CBCentralManagerDelegate,UNUserNotificationCenterDelegate {
    
    private static var centralManager : CBCentralManager!
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:  [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if let keys = launchOptions?.keys {
            if keys.contains(.location) {
                AppDelegate.centralManager = CBCentralManager(delegate: self, queue: nil)
                locationManager.requestAlwaysAuthorization()
                locationManager.allowsBackgroundLocationUpdates = true
                locationManager.pausesLocationUpdatesAutomatically = false
            }
        }
        return true
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral:CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {  
        AppDelegate.centralManager.connect(peripheral, options: nil)*
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        AppDelegate.centralManager.connect(peripheral, options: nil)
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        AppDelegate.centralManager.connect(peripheral, options: nil)    
    }
}

How long is this instance staying alive? I am noticing that it may last even five days, but I am not sure which parameters affect this.


Solution

  • Both significant location change notifications and BLE scan/connect notifications persist until cancelled. If your app is terminated by the os or there is a reboot, the system will re-launch your app to deliver them. There is no time limit on this.

    This does not mean, however, that your app is guaranteed to keep running. It may be terminated as usual if there is resource pressure (or when the system feels like it; Apple has changed the algorithm a few times over the years). It will just be re-launched.

    Regarding significant location changes, the CLLocationManager docs explain:

    If you start this service and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives.

    Regarding BLE, in order to continue scanning past a termination, you do need to implement State Preservation and Restoration for some cases. For details, see Performing Long-Term Actions in the Background in the Core Bluetooth Programming Guide. Connection requests similarly have no timeout. A connection request to a known device can run for weeks, and then re-launch your app when the device finally comes into range. This is an intentional feature and a supported use-case.

    Significant location change notifications and BLE scanning/connecting are very low-power. They are typically performed by "piggybacking" on other operations. For example, significant location changes are often based on the phone switching cell towers; something it has to deal with already.

    The side-effect, however, is that they are not promised to be highly responsive. For example, background BLE connection requests can take a minute or more to complete once the device comes into range, depending on how aggressively the device is advertising and whether it is using Apple's recommended timings.