我试图找到一种方法来扫描ble设备并将它们显示在uitableview中。BLE设备的扫描、连接、读写功能清晰有效!所以我的问题集中在“scantableview”和“bletouthmanager”类之间的交互。
这是我的两门课:

//  ScanTableView.swift

import UIKit

class ScanTableView: UITableViewController {

    @IBOutlet var scanTableView: UITableView!

    var bluetoothManager = BluetoothManager?()
    var tableViewScanTime = 5
    var timer1: NSTimer!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.refreshControl!.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let _ = bluetoothManager?.peripheralArray.count {
            return bluetoothManager!.peripheralArray.count
        }
        else {
            return 0
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = scanTableView.dequeueReusableCellWithIdentifier("scanCell",forIndexPath: indexPath)
        cell.textLabel!.text = bluetoothManager!.peripheralArray[indexPath.row].name
        cell.detailTextLabel!.text = bluetoothManager!.peripheralArray[indexPath.row].RSSI
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        bluetoothManager!.selectedPeripheral = bluetoothManager!.peripheralArray[indexPath.row]
        bluetoothManager!.connectPeripheral(bluetoothManager!.selectedPeripheral!)
    }

    func refresh() {
        scanTableView.userInteractionEnabled = false
        timer1 = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "scanTableViewRefresh", userInfo: nil, repeats: true)
        bluetoothManager = BluetoothManager()
    }

    func scanTableViewRefresh() {
        scanTableView.reloadData()
        tableViewScanTime--

        if tableViewScanTime <= 0 {
            timer1.invalidate()
            bluetoothManager!.CBmanager.stopScan()
            print("StopScan")
            tableViewScanTime = 5
            bluetoothManager!.peripheralArray.sortInPlace({$0.RSSI < $1.RSSI})
            self.refreshControl!.endRefreshing()
            self.scanTableView.userInteractionEnabled = true
        }
    }
}

//  BluetoothManager.swift

import UIKit
import CoreBluetooth

class BluetoothManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {

    struct BluetoothPeripheral {
        let name: String
        let UUID: String
        let RSSI: String
        let peripheral: CBPeripheral

        init(name: String, UUID: String, RSSI: NSNumber, peripheral: CBPeripheral) {
            self.name = "\(name)"
            self.UUID = "\(UUID)"
            self.RSSI = "\(RSSI)"
            self.peripheral = peripheral
        }
    }

    let DEVICE_NAME:String! = "TEST"

    //Creat an instance of ScanTableView Class
    var scanTableView: ScanTableView()


    var peripheralArray: [BluetoothPeripheral] = []
    var selectedPeripheral: BluetoothPeripheral?
    var characteristicArray: [CBCharacteristic] = []
    var CBmanager: CBCentralManager = CBCentralManager()
    var measurementValue: [[AnyObject?]] = [[]]

    //Basic functions
    override init() {
        super.init()
        CBmanager = CBCentralManager(delegate: self, queue: nil)
    }

    func connectPeripheral(selectedPeripheral: BluetoothPeripheral) {
        CBmanager.connectPeripheral(selectedPeripheral.peripheral, options: nil)
    }

    func disconnectPeripheral(selectedPeripheral: BluetoothPeripheral) {
        for characteristic in characteristicArray {
            selectedPeripheral.peripheral.setNotifyValue(false, forCharacteristic: characteristic as CBCharacteristic)
        }
        CBmanager.cancelPeripheralConnection(selectedPeripheral.peripheral)
    }

    func ScanForPeripherals() {
        CBmanager.scanForPeripheralsWithServices(nil, options: nil)
        print("Scanning")
    }

    func centralManagerDidUpdateState(central: CBCentralManager) {
        switch(central.state) {
        case .PoweredOn:
            CBmanager.scanForPeripheralsWithServices(nil, options: nil)
            print("scan")
        case .PoweredOff, .Resetting, .Unauthorized, .Unsupported, .Unknown:
            peripheralArray.removeAll()

            //This invokes an exception
            //scanTableView.scanTableView.reloadData()

            print("NO BLE!")
        }
    }

    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
        let UUID = "\(peripheral.identifier)".substringFromIndex("\(peripheral.identifier)".startIndex.advancedBy(31))
        if let peripheralName = peripheral.name {
            if peripheralName.containsString(DEVICE_NAME) {
                peripheralArray.append(BluetoothPeripheral(name: peripheral.name!, UUID: UUID, RSSI: RSSI, peripheral: peripheral))
                print(peripheralArray)
            }
        }
    }

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print("Connected")
        measurementValue.removeAll()
        peripheral.delegate = self
        selectedPeripheral!.peripheral.discoverServices(nil)
    }

    func centralManager(central: CBCentralManager, didFailToConnectPeripheral peripheral: CBPeripheral, error: NSError?) {
        print("Fail")
    }

    func centralManager(central: CBCentralManager, willRestoreState dict: [String : AnyObject]) {
        print("Restore")
    }

    func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) {
        print("Disconnected")
    }

    func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {
        for service in peripheral.services! {
            peripheral.discoverCharacteristics(nil, forService: service)
        }
    }

    func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {
        for characteristic in service.characteristics as [CBCharacteristic]!{
            if characteristic.properties.contains(CBCharacteristicProperties.Notify) {
                peripheral.discoverDescriptorsForCharacteristic(characteristic)
                peripheral.setNotifyValue(true, forCharacteristic: characteristic)
            }
        }
    }

    func peripheral(peripheral: CBPeripheral, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
        if characteristic.isNotifying {
            characteristicArray.append(characteristic as CBCharacteristic)
            peripheral.readValueForCharacteristic(characteristic)
        }
    }

    func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
        //Store new characteristic values
    }
}

现在我的问题是:
显示的代码可以工作,但我无法在两个类之间进行交互。
例如,我想从我的bluetouthmanager类重新加载打开的scantableview。那是不可能的…每次我尝试这个,我都会得到一个异常,我会打开一个可选的。为什么?“普通”类和GUI(uiTableView、uiView…)中显示的类之间有什么区别吗?我记录了异常行…
如果有人能告诉我在这种情况下该怎么办,那就太好了。
我很高兴有任何建议或改进!

最佳答案

正如@paulw11所说,我必须创建一个委托协议:

protocol BluetoothDelegate: class {

    func ReloadView()
}

此“ReloadView”方法在我的scanTableView类中声明:
func ReloadView() {
    scanTableView.reloadData()
}

现在,我不得不做一些额外的工作:
将BlueToothDelegate添加到ScanTableView类
声明变量“weak var delegate:bluetoutelegate?”在BlueToothManager类中
用“delegate”调用委托方法?.ReloadView()'在BlueToothManager类中的所需点
使用“bluetouthmanager”在scantableview中激活代理?.delegate=self'
就这样!

10-04 22:43