0

Je souhaite transférer un peu de mon code CoreBluetooth d'iOS vers OS X. J'ai configuré un ensemble partagé de wrappers CoreBluetooth qui sont consommés par à la fois une application iOS et une application OS X exactement de la même manière avec les mêmes périphériques BLE.CBPeripheral advertisementLes données sont différentes lors de la découverte de périphériques sous OSX et iOS (GAP/GATT)

Recherche de périphériques:

override init() { 
    super.init() 
    let queue = DispatchQueue.global(qos: .background) 
    centralManager = CBCentralManager(delegate: self, queue: queue) 
} 

func startScanning() { 
    let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: true] 
    let deviceUUID = CBUUID(string: Project.Service.Device) 
    let recoveryUUID = CBUUID(string: Project.Service.DFURecovery) 
    centralManager?.scanForPeripherals(withServices: [deviceUUID, recoveryUUID], options: options) 
} 

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){ 
    // Inspect advertisementData here to decipher what kind of device 
} 

Sur mon application iOS, didDiscoverPeripheral est tiré. Puis, quand je visite les données de publicité que je reçois toutes les clés/valeurs que j'attends:

{ 
    kCBAdvDataIsConnectable = 1; 
    kCBAdvDataLocalName = "My Device"; 
    kCBAdvDataManufacturerData = <34045254 5877f283 43fdd12d ff530978 45000000 000050c2 6500>; 
    kCBAdvDataServiceData =  { 
     Battery = <64>; 
    }; 
    kCBAdvDataServiceUUIDs =  (
     "My Inforamtion" 
    ); 
} 

Toutefois, lorsque ce code est exécuté (balayage pour les mêmes appareils) à partir d'une application OS X, les données de publicité est manquant certains des champs.

{ 
    kCBAdvDataIsConnectable = 1; 
    kCBAdvDataManufacturerData = <34045254 5877f36e 43fdd12d ff530978 45000000 000050c2 6500>; 
} 

Les paires clé/valeur suivantes sont manquantes dans advertisedData.

kCBAdvDataLocalName 
kCBAdvDataServiceData 
kCBAdvDataServiceUUIDs 

J'ai essayé d'ajouter ces clés aux scanForPeripherals appellent comme ceci:

let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: true, 
            CBAdvertisementDataLocalNameKey: true, 
            CBAdvertisementDataServiceDataKey: true, 
            CBAdvertisementDataServiceUUIDsKey: true] 
    let deviceUUID = CBUUID(string: Nightlight.Service.Device) 
    let recoveryUUID = CBUUID(string: Nightlight.Service.DFURecovery) 
    centralManager?.scanForPeripherals(withServices: [deviceUUID, recoveryUUID], options: options) 

Sans effet.

Répondre

0

OSX peut appeler didDiscoverPeripheral plusieurs fois par périphérique, chaque appel ayant des données de publication différentes. La solution que j'ai trouvée est d'écrire un cache.

importation Fondation importation CoreBluetooth

class AdvertisementDataCache { 

    fileprivate var map = [UUID: [String: Any]]() 

    func append(peripheral: CBPeripheral, advertisementData: [String: Any]) -> [String: Any] { 
     var ad = (map[peripheral.identifier]) ?? [String: Any]() 
     for (key, value) in advertisementData { 
      ad[key] = value 
     } 
     map[peripheral.identifier] = ad 
     return ad 
    } 

    func clear() { 
     map.removeAll() 
    } 
} 

Et puis dans didDiscoverPeripheral:

var advertisementDataCache = AdvertisementDataCache() 

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){ 
    let advertisementDataCache = self.advertisementDataCache.append(peripheral: peripheral, advertisementData: advertisementDataCache) 
    // cache may contain all 5 of the advertisements, depending on how may have been delivered 
    if let device = AdvertisementData.isTheDeviceIAmLookingFor(peripheral: peripheral, advertisementData: cache) { 
     // Do stuff with device 
    } 
}