We are integrating Auto-door unlock application for iOS. This app should start scanning for Beacons first, from didRangeBeacons in the region(), we get major & minor value, then we prepare a customized CBUUID Service using
and then start scanning for BLE Peripheral
App Launches -->
Start Scanning for iBeacon Region with UUID(uuidString: "{Provided UUID}") only (Minor value will be different)
when
callback is received,
we are extracting Major & Minor value from the detected beacon, preparing a Service UUID string based on this value
e.g. if the Major value is: 00 & Minor value is "11", concatenating this will be "0011" and adding this final value as a prefix of device service UUID e.g. "0011-xxxx-xxxx-xxxx-xxxxxxxxxxxx" to start scanning for BLE Peripheral.
So my BLECentralManager object would start scanning as
self?.bleCentralManager.scanForPeripherals(withServices: "0011-xxxx-xxxx-xxxx-xxxxxxxxxxxx", options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
Once the BLE Peripheral is detected, the rest of the BLE Operations are performed on this peripheral (i.e. Making a connection, sending data to a specific characteristic, and at last Drop the connection).
This works well in foreground mode.
Now, To Run the same operation for "App Not running state / Killed State", I have added the Location manager's didEnterRegion & didExitRegion monitoring.
I am getting a callback when a user enters into the beacon range and sends a local notification too. During this, we have started beacon ranging and initiated background task as below:
When beacon ranging identifies the beacon detail, I need to get major, minor value, prepare a CBUUID string (as mentioned above), make a connection, and process door-open operation (for app killed state)
but I am not getting a callback in
within 30 seconds time. I have read that backgroundTask can extend app time for 3 minutes. But I am getting 30/40 seconds hardly during iBeacon Ranging and unable to scan the BLE peripheral
Can you please help me how can I achieve the behaviour for Background mode?
Code Block computedService = CBUUID(string: "\(major+minor)-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
and then start scanning for BLE Peripheral
Code Block centralManager.scanForPeripherals(withServices: [computedService], options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
App Launches -->
Start Scanning for iBeacon Region with UUID(uuidString: "{Provided UUID}") only (Minor value will be different)
when
Code Block func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in the region: CLBeaconRegion)
callback is received,
we are extracting Major & Minor value from the detected beacon, preparing a Service UUID string based on this value
e.g. if the Major value is: 00 & Minor value is "11", concatenating this will be "0011" and adding this final value as a prefix of device service UUID e.g. "0011-xxxx-xxxx-xxxx-xxxxxxxxxxxx" to start scanning for BLE Peripheral.
So my BLECentralManager object would start scanning as
self?.bleCentralManager.scanForPeripherals(withServices: "0011-xxxx-xxxx-xxxx-xxxxxxxxxxxx", options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
Once the BLE Peripheral is detected, the rest of the BLE Operations are performed on this peripheral (i.e. Making a connection, sending data to a specific characteristic, and at last Drop the connection).
This works well in foreground mode.
Now, To Run the same operation for "App Not running state / Killed State", I have added the Location manager's didEnterRegion & didExitRegion monitoring.
I am getting a callback when a user enters into the beacon range and sends a local notification too. During this, we have started beacon ranging and initiated background task as below:
Code Block func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { guard region is CLBeaconRegion else { return } self.showLocalNotification(title: "Thank you", body: "You're in my region now!") manager.startRangingBeacons(in: region as! CLBeaconRegion) self.extendBackgroundRunningTime() } // Extending Background Execution Time func extendBackgroundRunningTime() { if (self.backgroundTask != .invalid) { return } self.backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "DummyTask", expirationHandler: { UIApplication.shared.endBackgroundTask(self.backgroundTask) self.backgroundTask = .invalid }) if threadStarted { print("Background task thread already started.") } else { threadStarted = true DispatchQueue.global(qos: .default).async { while (true) { Thread.sleep(forTimeInterval: 1); } } } }
When beacon ranging identifies the beacon detail, I need to get major, minor value, prepare a CBUUID string (as mentioned above), make a connection, and process door-open operation (for app killed state)
but I am not getting a callback in
Code Block func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
within 30 seconds time. I have read that backgroundTask can extend app time for 3 minutes. But I am getting 30/40 seconds hardly during iBeacon Ranging and unable to scan the BLE peripheral
Can you please help me how can I achieve the behaviour for Background mode?