2017-08-25 28 views
0

我正在製作核心藍牙應用程序,使用我的iPhone作爲外設,並將我的Mac作爲中央處理器。我的iPhone已打開並進行廣告宣傳,但在藍牙瀏覽器中,其他iPhone和Mac無法發現它。不過,我的朋友的Android手機可以發現它。這是怎麼回事? iOS的結束:爲什麼我的CBPeripheralManager廣告不可發現?

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") 
    } 
} 
} 

它打印出藍牙狀態打開和廣告。在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") 
} 
} 

它打印出藍牙已啓動,但它沒有發現任何東西。

+0

你如何試圖發現你的外設? –

+0

在設置中使用藍牙設備瀏覽器沒有發現它,我的Mac核心藍牙應用程序也沒有發現它。可以在必要時提供mac代碼 –

+0

@BrandonA我添加了Mac代碼 –

回答

1

我首選的掃描外設的方法是不明確地要求任何服務。我發現,當CBCentralManager有時無法從廣告本身指示服務時,該路線導致頭痛。

相反,你感興趣的是瞭解周邊的更可靠的方法是在你的scanForPeripheral參數未指定任何服務和掃描一切,只有一次。在您的options字典中包含CBCentralManagerScanOptionAllowDuplicatesKey密鑰,其值爲false包裝在NSNumber中。

而且當您收到didDiscover peripheral:的回撥方法時,請查看advertisingData。它將有一個名爲kCBAdvDataServiceUUIDs的字段。這將是您在外設上放置的一系列服務UUID。檢查這些(通常只有一個),看看是否有任何符合你感興趣的服務UUID,如果是的話,那些是你的外圍設備。


SCAN

注:通常我做這個固定的時間間隔的基礎上。

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

回調

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

這是最好的答案。 –

0

FYI代碼有工作就好了重新啓動後,所以很明顯,這是與藍牙核心毛刺。如果其他人有這個問題,一定要試試這個!

相關問題