mize
mize

Reputation: 13

Bluetooth background scan in Xamarin.iOS

I found the Objective-C examples

[manager scanForPeripheralsWithServices:nil
                                options:@{
    CBCentralManagerScanOptionSolicitedServiceUUIDsKey:@[
        [CBUUID UUIDWithString:@"7905F431-B5CE-4E99-A40F-4B1E122D00D0"]]}];

And try to convert Xamarin.iOS code

PeripheralScanningOptions option = new PeripheralScanningOptions(NSDictionary.FromObjectAndKey(CBCentralManager.ScanOptionSolicitedServiceUUIDsKey, CBUUID.FromString("84C80001-4A61-60B9-3A2B-1300855E588C")));

CBCM.ScanForPeripherals(new []{ CBUUID.FromString("84C80001-4A61-60B9-3A2B-1300855E588C") }, option);

but is not working,

how to use CBCentralManager.ScanOptionSolicitedServiceUUIDsKey in Xamarin.iOS?

Upvotes: 1

Views: 1546

Answers (4)

Piyush Kumar
Piyush Kumar

Reputation: 51

There is a solution below that you can try for you:

using Plugin.BLE (https://www.nuget.org/packages/Plugin.BLE/) I can get the service uuid of a beacon/device using advertisement records like so

foreach (AdvertisementRecord record in e.Device.AdvertisementRecords)

        {
            if (record.Type == AdvertisementRecordType.UuidsComplete128Bit || record.Type == AdvertisementRecordType.UuidsComplete16Bit)
            {
                b.ServiceUUID = record.Data;
                break;
            }
        }

I then pass in a list of CBUUID with the ServiceUUID values added to them:

 foreach (Beacon beacon in beaconList)
        {
            cbuuidList.Add(CBUUID.FromBytes(beacon.ServiceUUID));
        }

        CBUUID[] uuid = cbuuidList.ToArray();
        BLEManager.ScanForPeripherals(uuid);

Upvotes: 1

Michael
Michael

Reputation: 430

First of all you must enable the background mode for Bluetooth LE accessories, like Benjamin said.

Secondly, you must call ScanForPeripherals with a UUID, of the main service that is exposed in the advertising packet of the peripheral. This is a requirement for background BLE scanning, per Apple's docs. (https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html)

An example of a UUID is: 00000011-0000-1000-8000-00805F9B34FB, where 0011 at the end of the first segment is the short UUID of the service, and the rest is the BASE_UUID (https://www.bluetooth.com/specifications/assigned-numbers/service-discovery). This would scan for any peripherals advertising the Human Interface Device Profile (HID).

...
var serviceUuid = Guid.Parse("00000011-0000-1000-8000-00805F9B34FB");
var serviceUuids = new CBUUID[] { CBUUID.FromString(serviceUuid.ToString()) };
central.ScanForPeripherals(serviceUuids, new PeripheralScanningOptions { AllowDuplicatesKey = true });

This part is optional: new PeripheralScanningOptions { AllowDuplicatesKey = true }

Upvotes: 0

PlusInfosys
PlusInfosys

Reputation: 3436

Per the documentation, you need to set background capability for using it in background from info.plist file. Enable background mode and select use Bluetooth LE accessory.

Here is a screenshot of info.plist file with setting for using BLE in background. Screenshot

Upvotes: 1

poupou
poupou

Reputation: 43553

Your C# code does not look like the ObjC code.

[manager scanForPeripheralsWithServices:nil

means the first parameter is null, not an CBUUID array. This would be closer:

CBCM.ScanForPeripherals (null, option);

Also ObjC convention is to have object and keys (not keys and object) so the parameters you use with FromObjectAndKey should be reversed.

Upvotes: 1

Related Questions