扫描BLE外设并连接到它

时间:2018-11-28 19:19:34

标签: swift xcode bluetooth bluetooth-lowenergy

对于BLE来说是全新的,并且通常对移动应用程序进行编码。我已经尝试了几个演示,并遇到了这个https://github.com/RickRedSix/BLE4.0-iOS-Swift-Demo 问题是它没有连接到我的BLE设备,因此我假设它仅扫描当时的BLE设备创建者,因此我总是收到错误“仅在通电状态下才能接受此命令”。我需要更改代码中的任何部分以使其扫描另一个外围设备吗?我需要在某处指定设备的UUID,MAC地址或其他唯一信息吗?

感谢有关此问题的任何帮助

2 个答案:

答案 0 :(得分:1)

大约一年前,我曾开发过一个应用程序,用于扫描并连接到BLE设备。从该项目发布代码。如果您完全按原样粘贴,则可能无法正常工作。但是我100%确信这正是您想要实现的目标。

我也使用“ https://github.com/RickRedSix/BLE4.0-iOS-Swift-Demo”作为参考。

希望这可以帮助您解决问题。如果您有任何疑问,请告诉我。

import UIKit
import CoreLocation
import CoreBluetooth

class BLEDeviceTableViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource, CBCentralManagerDelegate, CBPeripheralDelegate {

private var myTableView: UITableView!

var manager : CBCentralManager!
var myBluetoothPeripheral = [CBPeripheral]()
var myCharacteristic : CBCharacteristic!

var isMyPeripheralConected = false

var peripheralNames = [String]()


override func viewDidLoad() {
    super.viewDidLoad()

    let displayWidth: CGFloat = self.view.frame.width

    manager = CBCentralManager(delegate: self, queue: nil)

    myTableView = UITableView(frame: CGRect(x: 0, y: 135, width: displayWidth, height: (self.view.frame.height-(self.view.frame.height/3))-10))
    myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
    myTableView.dataSource = self
    myTableView.delegate = self
    self.view.addSubview(myTableView)

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

func centralManagerDidUpdateState(_ central: CBCentralManager) {

    var msg = ""

    switch central.state {

    case .poweredOff:
        msg = "Bluetooth is Off"
    case .poweredOn:
        msg = "Bluetooth is On"
        manager.scanForPeripherals(withServices: nil, options: nil)
    case .unsupported:
        msg = "Not Supported"
    default:
        msg = ""

    }

    print("STATE: " + msg)

}

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



    peripheralNames.append(peripheral.name ?? "Unknown Device")
    print(peripheral)


    self.myBluetoothPeripheral.append(peripheral)      //save peripheral

    print(peripheralNames)
    myTableView.reloadData()
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("Connected to \(peripheral.name ?? "Uknown Device")")
    availableDeviceLabel.text = "Connected to \(peripheral.name ?? "Uknown Device")"
    isMyPeripheralConected = true //when connected change to true
    peripheral.delegate = self
    peripheral.discoverServices(nil)
}

func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
    isMyPeripheralConected = false //and to falso when disconnected
}


func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

    print("Services:\(String(describing: peripheral.services)) and error\(String(describing: error))")
    if let services = peripheral.services {
        for service in services {
            peripheral.discoverCharacteristics(nil, for: service)
        }
    }

}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {


    print("peripheral:\(peripheral) and service:\(service)")

    for characteristic in service.characteristics!
    {
        peripheral.setNotifyValue(true, for: characteristic)
    }

}

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

    let readValue = characteristic.value

    print("Response from BLE Device: \(readValue)")

}

//if you want to send an string you can use this function.
func writeValue() {

    if isMyPeripheralConected {

        //check if myPeripheral is connected to send data

        //let dataToSend: Data = "Hello World!".data(using: String.Encoding.utf8)!

        //myBluetoothPeripheral.writeValue(dataToSend, for: myCharacteristic, type: CBCharacteristicWriteType.withoutResponse)    //Writing the data to the peripheral

    } else {
        print("Not connected")
    }
}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    //let indexPath = NSIndexPath(forRow: tag, inSection: 0)
    //let cell = tableView.cellForRow(at: indexPath) as! gpsSettingsCustomCell!
    //print(cell?.cellLabel.text ?? "")

    self.myBluetoothPeripheral[indexPath.row].delegate = self

    manager.stopScan()                          //stop scanning for peripherals
    manager.connect(myBluetoothPeripheral[indexPath.row], options: nil)

    myTableView.deselectRow(at: indexPath, animated: true)
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return peripheralNames.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = gpsSettingsCustomCell(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 60), title: "Hello")
    cell.cellLabel.text = peripheralNames[indexPath.row]
    cell.cellLabel2.text = "Bluetooth Device"
    return cell

}

class BLEDeviceCustomCell: UITableViewCell {
//var cellButton: UIButton!
var cellLabel: UILabel!
var cellLabel2: UILabel!

init(frame: CGRect, title: String) {
    super.init(style: .default, reuseIdentifier: "cell")
    //super.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")

    cellLabel = UILabel(frame: CGRect(x: 10, y: 10, width: self.frame.width, height: 20))
    cellLabel.font = UIFont(name: "Titillium-Regular", size: 14.0)
    //cellLabel= UILabel(frame: CGRectMake(self.frame.width - 100, 10, 100.0, 40))
    cellLabel.textColor = UIColor.black
    //cellLabel.font = //set font here

    cellLabel2 = UILabel(frame: CGRect(x: 10, y: 30, width: self.frame.width, height: 20))
    cellLabel2.font = UIFont(name: "Titillium-Regular", size: 14.0)
    cellLabel2.textColor = UIColor.gray
    //cellButton = UIButton(frame: CGRectMake(5, 5, 50, 30))
    //cellButton.setTitle(title, forState: UIControlState.Normal)

    addSubview(cellLabel)
    addSubview(cellLabel2)
    //addSubview(cellButton)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
}

答案 1 :(得分:0)

该消息表示您应该打开蓝牙电源,然后搜索设备。像这样:

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .unknown:
        print("Unknown")
    case .resetting:
        print("Resetting")
    case .unsupported:
        print("Unsupported")
    case .unauthorized:
        print("Unauthorized")
    case .poweredOff:
        print("Powered Off")
        central.stopScan()
    case .poweredOn:
        print("Powered On")
        central.scanForPeripherals(withServices: nil, options: nil)
    }
}