2017-08-25 2 views
0

Je fais une application bluetooth de base en utilisant mon iPhone comme périphérique et mon mac comme centrale. Mon iPhone est allumé et la publicité, mais dans le navigateur bluetooth d'autres iPhones et Macs ne peuvent pas le découvrir. Cependant, le téléphone Android de mon ami peut le découvrir. Que se passe-t-il? fin iOS:Pourquoi ma publicité CBPeripheralManager n'est-elle pas détectable?

import UIKit 
import CoreBluetooth 

class ViewController: UIViewController, CBPeripheralManagerDelegate { 

@IBOutlet weak var statusLabel: UILabel! 
@IBOutlet weak var connectionInfoLabel: UILabel! 
var peripheralManager: CBPeripheralManager! 
var accelerometerXCharacteristic: CBMutableCharacteristic! 
var phoneDataService: CBMutableService! 
var accelerometerXData: Data! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    connectionInfoLabel.isHidden = true 
    //Ignore this I was testing the data encoding 
    let accelerometerVal = "45" 
    let someData = accelerometerVal.data(using: String.Encoding.utf8) 
    let revertedString = String(data: someData!, encoding: String.Encoding.utf8)! as String 
    let integer = Int(revertedString)! 
    print(integer) 

    setupBT(delegate: self, intialXData: someData!) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func setupBT(delegate: CBPeripheralManagerDelegate, intialXData: Data) { 
    peripheralManager = CBPeripheralManager(delegate: delegate, queue: nil) 
    //print(peripheralManager.state) 

    let accelerometerXCharacteristicUUID = CBUUID(string: "07B24C73-C35B-45C7-A43D-58240E3DB4DF") 
    let phoneDataServiceUUID = CBUUID(string: "CAB1B028-2243-4F2C-A2F1-3BE5AD51AD61") 

    accelerometerXCharacteristic = CBMutableCharacteristic(type: accelerometerXCharacteristicUUID, properties: CBCharacteristicProperties.read, value: intialXData, permissions: CBAttributePermissions.readable) 

    phoneDataService = CBMutableService(type: phoneDataServiceUUID, primary: true) 
    phoneDataService.characteristics = [accelerometerXCharacteristic] 



} 

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { 
    var statusMessage = "" 

    switch peripheral.state { 
    case .poweredOn: 
     statusMessage = "Bluetooth Status: Turned On" 
     peripheralManager.add(phoneDataService) 
     peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [phoneDataService.uuid], CBAdvertisementDataLocalNameKey: "DSiPhone"]) 

    case .poweredOff: 
     statusMessage = "Bluetooth Status: Turned Off" 

    case .resetting: 
     statusMessage = "Bluetooth Status: Resetting" 

    case .unauthorized: 
     statusMessage = "Bluetooth Status: Not Authorized" 

    case .unsupported: 
     statusMessage = "Bluetooth Status: Not Supported" 

    default: 
     statusMessage = "Bluetooth Status: Unknown" 
    } 

    print(statusMessage) 

} 

func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { 
    if ((error) != nil) { 
     print("Error \(error!.localizedDescription)") 
    } 
} 

func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) { 
    print("Advertising") 
    if ((error) != nil) { 
     print("Error advertising \(error!.localizedDescription)") 
    } 
} 

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) { 
    var requestedCharacteristic: CBMutableCharacteristic? 
    switch request.characteristic.uuid { 
    case accelerometerXCharacteristic.uuid: 
     requestedCharacteristic = accelerometerXCharacteristic 
    default: 
     requestedCharacteristic = nil 

    } 
    if let characteristic = requestedCharacteristic { 
     if request.offset > characteristic.value!.count { 
      request.value = characteristic.value?.subdata(in: request.offset..<(characteristic.value!.count - request.offset)) 
      peripheralManager.respond(to: request, withResult: CBATTError.success) 
     } else { 
      peripheralManager.respond(to: request, withResult: CBATTError.invalidAttributeValueLength) 
     } 
    } else { 
     peripheralManager.respond(to: request, withResult: CBATTError.attributeNotFound) 
    } 
} 

func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) { 
    print("Connection Successful") 
    statusLabel.text = "Successful!" 
    let didSendValue = peripheralManager.updateValue(accelerometerXData, for: characteristic as! CBMutableCharacteristic, onSubscribedCentrals: nil) 
    if !didSendValue { 
     print("Send failed") 
    } 
} 
} 

C'est l'impression que le statut Bluetooth est activé et la publicité. Sur la fin Mac:

import Cocoa 
import CoreBluetooth 

class ViewController: NSViewController, CBCentralManagerDelegate { 
var centralManager: CBCentralManager! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    centralManager = CBCentralManager(delegate: self, queue: nil) 

    // Do any additional setup after loading the view. 
} 

override var representedObject: Any? { 
    didSet { 
    // Update the view, if already loaded. 
    } 
} 

func setupBT() { 

} 

func centralManagerDidUpdateState(_ central: CBCentralManager) { 
    var statusMessage = "" 
    switch central.state { 
    case .poweredOn: 
     centralManager.scanForPeripherals(withServices: [CBUUID(string: "CAB1B028-2243-4F2C-A2F1-3BE5AD51AD61")], options: nil) 
     statusMessage = "Bluetooth Status: Turned On" 

    case .poweredOff: 
     statusMessage = "Bluetooth Status: Turned Off" 

    case .resetting: 
     statusMessage = "Bluetooth Status: Resetting" 

    case .unauthorized: 
     statusMessage = "Bluetooth Status: Not Authorized" 

    case .unsupported: 
     statusMessage = "Bluetooth Status: Not Supported" 

    default: 
     statusMessage = "Bluetooth Status: Unknown" 
    } 

    print(statusMessage) 
} 

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

Il est l'impression que Bluetooth est sous tension, mais il ne rien découvrir.

+0

Comment tentez-vous de découvrir votre périphérique? –

+0

L'utilisation du navigateur de périphérique Bluetooth dans les paramètres ne l'a pas détecté et mon application Mac Core Bluetooth non plus. Peut fournir un code mac si nécessaire –

+0

@BrandonA J'ai ajouté le code Mac –

Répondre

1

Ma méthode préférée pour rechercher des périphériques est de ne demander explicitement aucun service en particulier. J'ai trouvé que cette voie mène à des maux de tête quand CBCentralManager échoue parfois à indiquer le service des publicités elles-mêmes. Au lieu de cela, la manière la plus fiable de découvrir le périphérique qui vous intéresse est de ne spécifier aucun service dans votre paramètre scanForPeripheral et de rechercher tous les éléments, une seule fois. Dans votre dictionnaire options inclure la clé CBCentralManagerScanOptionAllowDuplicatesKey avec une valeur de false enveloppé dans un NSNumber.

Et lorsque vous recevez le rappel de didDiscover peripheral: méthode regardez dans le advertisingData. Il aura un champ appelé kCBAdvDataServiceUUIDs. Ce sera un tableau d'UUID de service que vous avez placé sur votre périphérique. Vérifiez-les (en général un seul) et voyez si les UUID de service qui vous intéressent correspondent, si c'est le cas, ce sont vos périphériques.


SCAN

Note: En général, je le fais sur une base intervalle de temps.

let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)] 
centralManager?.scanForPeripherals(withServices: nil, options: options) 

CALLBACK

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
    if let ids = advertisementData["kCBAdvDataServiceUUIDs"] as? [CBUUID], 
    let id = ids.first, 
    id == CBUUID(string: "YourServiceID") { 
     print("Found Peripheral \(peripheral)") 
    } 
} 
+0

Ceci est la meilleure réponse. –

0

Pour votre information, que le code a travaillé là-bas très bien après un redémarrage, donc évidemment cela a été un petit problème avec Bluetooth Core. Si quelqu'un d'autre a ce problème, essayez vraiment ceci!