首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的CBPeripheralManager广告不能被发现?

为什么我的CBPeripheralManager广告不能被发现?
EN

Stack Overflow用户
提问于 2017-08-25 18:56:54
回答 2查看 1.6K关注 0票数 3

我正在制作一个核心蓝牙应用程序,使用我的iPhone作为外围设备,我的mac作为中心。我的iPhone是打开和广告,但在蓝牙浏览器,其他iPhones和Mac无法发现它。然而,我朋友的Android手机可以发现它。到底怎么回事?iOS端:

代码语言:javascript
复制
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端:

代码语言:javascript
复制
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")
}
}

这是打印出来的蓝牙电源,但它没有发现任何东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-26 15:55:59

在重新启动之后,那里的代码工作得很好,所以很明显这是核心蓝牙的一个小故障。如果其他人有这个问题,一定要试试这个!

票数 1
EN

Stack Overflow用户

发布于 2017-08-25 21:48:44

我最喜欢的扫描外设的方法是不明确地要求任何服务。我发现,当CBCentralManager有时无法显示广告本身的服务时,走这条路线会让人头疼。

相反,发现您感兴趣的外围设备的更可靠的方法是,不要在scanForPeripheral参数中指定任何服务,只扫描一次。在options字典中,包含CBCentralManagerScanOptionAllowDuplicatesKey键,其值为false,包装在NSNumber中。

当您收到来自didDiscover peripheral:方法的回调时,请查看advertisingData。它将有一个名为kCBAdvDataServiceUUIDs的字段。这将是您在外围设备上放置的服务UUID的数组。检查这些(通常只是一个),看看是否有任何与您感兴趣的服务UUID相匹配,如果是,这些就是您的外围设备。

扫描

注意:通常情况下,我是在时间间隔的基础上这样做的。

代码语言:javascript
复制
let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)]
centralManager?.scanForPeripherals(withServices: nil, options: options)

回调

代码语言:javascript
复制
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)")
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45887882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档