如何在 swift Xcode 中以编程方式绑定/配对蓝牙 LE 设备?

Posted

技术标签:

【中文标题】如何在 swift Xcode 中以编程方式绑定/配对蓝牙 LE 设备?【英文标题】:How to bond/pair to a bluetooth LE device programmatically in swift Xcode? 【发布时间】:2017-01-17 07:10:11 【问题描述】:

我目前正在尝试开发和应用程序,允许用户通过单击按钮绑定到外围设备,密码将自动输入。

是否可以使用 swift 以编程方式绑定和删除绑定?

【问题讨论】:

你不能,这取决于用户只回答配对警报弹出窗口。 如何使用 swift 启动配对? 您需要读取一个需要加密的属性(其中属性包括CBCharacteristicPropertyIndicateEncryptionRequired)。 @Mysterious_android 你找到答案了吗? 【参考方案1】:

只要您尝试写入或读取 BLE 设备上的特征,就会启动配对。但是,如果设备未设置为要求身份验证和/或绑定,您将不会看到请求 PIN 码的 ios 弹出窗口。

我在使用 HM-10 时遇到了这个问题,因为我可以使用 Core Bluetooth (via Swift) function writeValue() 将数据写入特征,而不会看到配对弹出窗口。

直到我仔细阅读了 HM-10(实现 IC cc2451)数据表并发现我需要将 AT+TYPE 设置为值 3 时才弄清楚。它默认为 0,这意味着 HM -10 不需要配对/绑定,因此您永远不会看到 iOS 弹出窗口。

您可以阅读更多关于我提出问题并最终找到解决方案并将其写下来的详细信息:How do I pair and/or bond to BLE on iOS using Swift code and an HM-10 so data sent is encrypted?

【讨论】:

我不知道这是否是要问的地方,但我在 *** 上问了一个问题,关于知道配对/绑定何时完成。我一直在探索 CBPeripheralDelegate,绑定完成后没有任何调用。我想知道绑定何时完成,以便我可以开始读/写安全特性。 ***.com/questions/56814487/… @Biclops 我也遇到了一些麻烦,因为我在 iOS 中找不到让我知道配对已完成或成功的方法。在我的测试过程中,即使用户在配对对话框中点击了取消,我也能够(通过我的 iOS 应用程序)向我的 BLE 设备发送数据。对我来说,这似乎是 iOS API 中的一个漏洞,但我不确定。【参考方案2】:

按照步骤将 Ble 设备连接到 iOS 程序。

1) 导入

import CoreBluetooth

2) 将变量声明到类或 ViewController 中。

  let kServiceUART = CBUUID(string: "0x1800")
 var peripheralHeartRateMonitor: CBPeripheral?

var cbManger: CBCentralManager!

3) 将cbManger初始化为viewController的ViewDidLoad函数或类的initialize函数。

  cbManger = CBCentralManager(delegate: self, queue: .main)

4) 覆盖 CBCentralManager 的委托方法。

 func centralManagerDidUpdateState(_ central: CBCentralManager) 

    switch central.state 
    case .unsupported:
        print("BLe Unsupported")
        break
    case .unauthorized:
         print("BLe unauthorized")
        break
    case .poweredOff:
        let alertMessgesInst = AlertMessages.sharedInstance
        CommonUtils.showAlert(alertMessgesInst.actofit_Title, message: alertMessgesInst.trun_On_blueTooth)
        break
    case .poweredOn:

        if isNewFirmWareOFImpulse 

            let uuidString = StorageServices.readFromDefaults(key: Constants.userDefaultKeys.impulseUUID)
            let uuid = UUID(uuidString:uuidString as! String )
            let device =  cbManger.retrievePeripherals(withIdentifiers: [uuid!])
            peripheralHeartRateMonitor = device.first
            peripheralHeartRateMonitor!.delegate = self
            cbManger?.connect(peripheralHeartRateMonitor!)

        else 

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

        break
    case .unknown:
         print("BLe unknown")
        break
    default:
        break
     // End Swith

 // End 'centralManagerDidUpdateState' function.
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) 

    if isNewFirmWareOFImpulse 

        peripheralHeartRateMonitor = peripheral
        print("UUid of band is :- \(peripheralHeartRateMonitor?.identifier.uuidString)")

        if impulseName == peripheral.name 


            peripheralHeartRateMonitor!.delegate = self


            cbManger.stopScan()

            // STEP 6: connect to the discovered peripheral of interest
            cbManger?.connect(peripheralHeartRateMonitor!)


         // End impulse condition

    else 

        let keysArray = advertisementData.keys

        if let tempImpulseName = peripheral.name 
            print(impulseName + " and " + tempImpulseName )
            if impulseName == tempImpulseName 
                for key in keysArray 
                    if key == "kCBAdvDataManufacturerData"
                        let manufactureData = advertisementData[key]
                        if let stringValue = manufactureData.debugDescription as? String 

                            var heartValue: String = String()
                            heartValue = stringValue
                            heartValue.removeLast()
                            heartValue.removeLast()
                            let last = heartValue.removeLast()
                            let secondLast = heartValue.removeLast()

                            let hR = String([secondLast, last])
                            if let value = UInt8(hR, radix: 16)

                                if Int(value) > 60 
                                    hrArray.append(Int(value))
                                


                             // End the value block

                         // end of if 'stringValue' condition
                     // end 'Key' if condition

                 // End for each loop
             // End impulse condition

         // End pheripheral if condition

     // end version condition

 // End function 'didDiscover peripheral'.

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) 


    // STEP 8: look for services of interest on peripheral

    peripheralHeartRateMonitor?.discoverServices(nil)

 // END func centralManager(... didConnect peripheral

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) 
    if error != nil 

【讨论】:

以上是关于如何在 swift Xcode 中以编程方式绑定/配对蓝牙 LE 设备?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Xcode 8 和 Swift 3 在 SpriteKit 中以编程方式触发 segue

如何在 Swift 3 中以编程方式在 UIImageview 中添加 UITableview

如何在 SWIFT 中以编程方式将我的自定义控制器变成根控制器? (无法加载 NIB)

使用 Cocoa 在 Swift 4.0 中以编程方式创建复选框的标准方法是啥?

有没有办法在Swift中以编程方式设置NSCollectionView?

如何在 Swift 中以编程方式将 UILabel 对象居中?