0

I have an app which is working in background. I use CBPeripheralManager to Advertising and CBCentralManager to scan. I use two ıos (IOS 11.3 and IOS 13.4.1) device. First one is advertising foreground and background. Second one is scan foreground and background. I can scan;

App in the background, phone is unlocked - Works perfect

App in background, phone is locked, screen is lighted - Works perfect

App in background, phone locked, screen is off - Doesn't work!

/* I check it Advertising app which run background show in Android Device */

What is the problem. Please let me know. How can solve this problem? I want to scan both in background. My code is given bellow;

let scanOptions = [
        CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: true)
    ]

let services = [CBUUID(string: "e2c56db5-dffb-48d2-b060-d0f5a71096e0")]

let advertisingData = [
        CBAdvertisementDataLocalNameKey: "xxx",
        CBAdvertisementDataServiceUUIDsKey:[CBUUID(string: "e2c56db5-dffb-48d2-b060-d0f5a71096e0")]
        ] as [String : Any]

func initLocal() {

        peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
        cbCentralManager = CBCentralManager(delegate: self, queue: nil,options: nil)

    }

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {

        if peripheral.state == .poweredOn {
            peripheralManager.startAdvertising(advertisingData)
        }
       else if peripheral.state == .poweredOff {
            peripheralManager.stopAdvertising()
        }
    }

func centralManagerDidUpdateState(_ central: CBCentralManager) {

        if central.state == .poweredOn{

            central.scanForPeripherals(withServices: services,options:scanOptions)
            print("scanning...")

        }
        else {
            print("Bluetooth is not active")
        }
    }

func centralManager(_ central: CBCentralManager,didDiscover peripheral: CBPeripheral,advertisementData: [String : Any],
                        rssi RSSI: NSNumber)
    {

        print("RSSI   : \(RSSI)")

    }

This is my info.plist;enter image description here

uyarc
  • 579
  • 4
  • 17

1 Answers1

1

You seem to be expecting duplicates since you've set CBCentralManagerScanOptionAllowDuplicatesKey. That key is ignored in the background. If you're expecting to see the same device more than once via advertising, that's impossible. Discovering new devices that you haven't seen before should work, however. Are you having trouble with that? (You should explain the details of exactly how you're testing this, what precise behaviors you see, and what you expect to see. Bluetooth is very subtle. The details matter quite a lot, and "not working" is far too vague.)

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks. I am expecting to see the same device more than once via advertising like when app in foreground. You say thats impossible. Right? Maybe it's a very different question, but how can calculate the distance between the devices while it is in the background in certain time. – uyarc May 07 '20 at 20:42
  • Correct; that's impossible. Calculating the distances is very hard-to-impossible in the foreground, and completely impossible in the background. You can get very rough ideas of distance using RSSI in the foreground, but there are so many caveats, that it's barely useful (walls, reflections, orientation of the devices, signals passing through giant-bags-of-microwave-absorbing-water-called-people). But none of that is possible in the background with advertising. – Rob Napier May 07 '20 at 21:08
  • This general problem is impossible, but for certain subsets it's buildable (I do various work in that space). What's the actual goal? As long as it's not something like a contact tracing app, it might be solvable. – Rob Napier May 07 '20 at 21:16
  • Thanks. I know. The purpose of the application is to calculate the approximate distances of the devices to each other by using bluetooth signals with a background app that will work on two different devices. – uyarc May 08 '20 at 06:43
  • 1
    If it's just two devices (or any small number of known devices), you would want to use a connection rather than advertising. Devices can connect to known devices in the background pretty reliably, and can wake each other up by exchanging data. RSSI is not reliable, but is available, and when mixed with some augmentation with CoreLocation can possibly meet the need. – Rob Napier May 08 '20 at 13:49
  • When the device locks all the way, advertising and scanning are both throttled. You have to get lucky that they see each other (and remember, you will almost certainly never get a device you've seen before). You should use another device (your Mac for example) to verify whether the advertising device is continuing to advertise at all. (I generally use BlueSee on Mac for that, and LightBlue on iOS. Occasionally I use a hardware sniffer like Ubertooth.) You will need to document your procedure very carefully. And remember, my expectation is that this is impossible. – Rob Napier May 09 '20 at 14:08