2016-07-04 1 views
0

저는 BLE 장치를 테이블에서 연결하기 위해 코드를 작성했습니다. 장치를 발견하여 테이블에로드 할 수 있습니다. 테이블 내에서 행을 선택하면 선택한 장치가 연결되도록 요청합니다. 그러나 didConnectPeripheral가 호출되지 않습니다 ...centralManager didConnectPeripheral이 호출되지 않습니다.

어떤 생각 : 나는 관찰자를 가능한 한 코드가 테이블에서 호출되는 알고

import UIKit 
import CoreBluetooth 

@objc protocol BLEDelegate: class { 

    func srgDiscoverServices(sender: BLEDiscovery, peripheral: CBPeripheral) 

} 

let bleDiscoverySharedInstance = BLEDiscovery() 

//MARK: - UUIDS for StingRay Genessis M (SRG) 
let StingRayGenesisMUUID = CBUUID (string: "346D0000-12A9-11CF-1279-81F2B7A91332") //Core UUID 

//MARK: - Device and Characteristic Registers 
var BLEDevices   : [CBPeripheral] = []   //Device Array 
var BLECharDictionary = [String: CBCharacteristic]() //Characteristic Dictionary 


class BLEDiscovery: NSObject, CBCentralManagerDelegate { 

    private var centralManager : CBCentralManager? 

    weak var delegate: BLEDelegate? 

    override init() { 
     super.init() 

     let centralQueue = dispatch_queue_create("com.stingray", DISPATCH_QUEUE_SERIAL) 
     centralManager = CBCentralManager(delegate: self, queue: centralQueue) 

    } 

    // MARK: - CBCentralManager 
    func centralManagerDidUpdateState(central: CBCentralManager) { 
     switch (central.state) { 

      case CBCentralManagerState.PoweredOff: 
       print("CBCentralManagerState.PoweredOff") 

      case CBCentralManagerState.Unauthorized: 
       // Indicate to user that the iOS device does not support BLE. 
       print("CBCentralManagerState.Unauthorized") 
       break 

      case CBCentralManagerState.Unknown: 
       // Wait for another event 
       print("CBCentralManagerState.Unknown") 
       break 

      case CBCentralManagerState.PoweredOn: 
       print("CBCentralManagerState.PoweredOn") 
       self.startScanning() 

      case CBCentralManagerState.Resetting: 
       print("CBCentralManagerState.Resetting") 

      case CBCentralManagerState.Unsupported: 
       print("CBCentralManagerState.Unsupported") 
       break 
     } 
    } 

    // MARK: - Start scanning for StringRay devices with the appropriate UUID 
    func startScanning() { 
     if let central = centralManager { 
      central.scanForPeripheralsWithServices([StingRayGenesisMUUID], options: nil) 
     } 
    } 

    // MARK: - CB Central Manager - Did discover peripheral (follows : startScanning) 
    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) { 

     print("BLEDiscovery :: didDiscoverPeripheral :: ", peripheral.name) 

     //Check if new discovery and append to BLEDevices where required 
     if BLEDevices.contains(peripheral) { 

     } 
     else{ 
      BLEDevices.append(peripheral) 
     } 

     //Change to BLEDevices - therefore update MianViewController, but check that the view is loaded 
     if MainViewController().deviceTableView != nil { 

      print("BLEDiscovery :: deviceTableView :: ") 
      MainViewController().relaodDeviceTable() 
     } 


    } 

    // MARK: - CB Central Manager - Connect and Disconnet BLE Devices 

    func connectBLEDevice (peripheral: CBPeripheral){ 

     print("BLEDiscovery :: connectBLEDevice :: ", peripheral.name) 

     //Connect 
     let peripheralConnect : CBPeripheral = peripheral 
     self.centralManager!.connectPeripheral(peripheralConnect, options: nil) 
    } 

    func disconnectBLEDevice (peripheral: CBPeripheral){ 

     print("BLEDiscovery :: disconnectBLEDevice :: ", peripheral.name) 

     //Disconnect 
     let peripheralDisconnect : CBPeripheral = peripheral 
     self.centralManager?.cancelPeripheralConnection(peripheralDisconnect) 
    } 

    // MARK: - CB Central Manager - Did Connect Device 

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) { 

     print("BLEDiscovery :: didConnectPeripheral :: ", peripheral.name) 

     delegate?.srgDiscoverServices(self, peripheral: peripheral) 

    } 

    func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) { 

     //error handling 
     if (error != nil) { 
      print("!!Error - BLE Discovery - didDisconnectPeripheral - Error :: \(error)") 
      return 
     } 

     //On disconnect remove device from register 
     if let index = BLEDevices.indexOf(peripheral) { 
      BLEDevices.removeAtIndex(index) 
     } 

     //Change to BLEDevices - therefore update MianViewController 
     MainViewController().relaodDeviceTable() 

    } 

    func centralManager(central: CBCentralManager, didFailToConnectPeripheral peripheral: CBPeripheral, error: NSError?) { 

     //error handling 
     if (error != nil) { 
      print("!!Error - BLE Discovery - didFailToConnectPeripheral - Error :: \(error)") 
      return 
     } 

     //Change to BLEDevices - therefore update MianViewController 
     MainViewController().relaodDeviceTable() 

    } 


} 

"BLEDiscovery :: connectBLEDevice ::"peripheral.name " 같은 BLEDiscovery 가장 구현 당신으로

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

     print("MainViewController :: didSelectRowAtIndexPath :: Row :: ", deviceTableView.indexPathForSelectedRow?.row) 

     let peripheral : CBPeripheral = BLEDevices[(deviceTableView.indexPathForSelectedRow?.row)!] 

     switch peripheral.state{ 

     case .Connected: 
      //Disconnect as device is connected 
      BLEDiscovery().disconnectBLEDevice(peripheral) 
     case .Disconnected: 
      //Connect as device as disconnected 
      BLEDiscovery().connectBLEDevice(peripheral) 

     default: break 

     } 

    } 
+0

이것은 문제가 아니지만 기본보기 컨트롤러가 싱글 톤입니까? MainViewController()를 사용하지 않으면 필요한 인스턴스가 제공되지 않습니다. 'connectBLEDevice'라고 부를 수 있습니까? 'didSelectRowAtIndexPath'에? 귀하의 'BLEDiscovery' 객체는 싱글 톤이어야하며 주변 배열은 전역이 아닌이 클래스의 속성이어야합니다 – Paulw11

답변

0

객체 :. 난에서 연결 및 분리 전화 위치를 로그 창에

입니다 싱글 톤으로 사용하거나 Dependency Injection을 사용할 수 있지만 가장 중요한 것은 클래스의 단일 인스턴스를 갖는 것입니다.

목표를 달성하기 위해 전역을 사용하고 있지만 사용자의 didSelectRowAtIndexPath 기능을 사용하지 않았습니다. 당신이

case .Connected: 
    //Disconnect as device is connected 
    BLEDiscovery().disconnectBLEDevice(peripheral) 

을 말할 때 당신은 CBCentralManager 자신을 포함 BLEDiscovery의 새로운 지역, 인스턴스를 만들고이 당신이 연결을 수행하기 위해 요구 중심이다. case 문을 종료하자마자이 로컬 BLEDiscovery이 릴리스 될 것이므로 대리자 메서드는 호출되지 않습니다. 전역 배열을 사용하지 않고 주변기기 배열을 BLEDiscovery 클래스에 캡슐화 한 경우 배열에 액세스하기 전에 BLEDiscovery 참조를 가져와야하므로이 오류를 발견했을 수 있습니다. 그러면 어레이 경계 예외가 배열로 발생합니다 비어 있었을 것이다.

당신은 전역 당신의 BLEDiscovery가 싱글로 구조 조정 및 제거 할 수 있습니다 :

class BLEDiscovery: NSObject, CBCentralManagerDelegate { 

    static let sharedInstance = BLEDiscovery() 
    private static var initialised = false 

    private var centralManager : CBCentralManager! 

    weak var delegate: BLEDelegate? 

    //MARK: - UUIDS for StingRay Genesis M (SRG) 
    let stingRayGenesisMUUID = CBUUID (string: "346D0000-12A9-11CF-1279-81F2B7A91332") //Core UUID 

    //MARK: - Device and Characteristic Registers 
    var bleDevices   : [CBPeripheral] = []   //Device Array 
    var bleCharDictionary = [String: CBCharacteristic]() //Characteristic Dictionary 

    override init() { 
     assert(!BLEDiscovery.initialised, "Illegal call to initializer - use sharedInstance") 

     BLEDiscovery.initialised = true 

     super.init() 

     let centralQueue = dispatch_queue_create("com.stingray", DISPATCH_QUEUE_SERIAL) 
     centralManager = CBCentralManager(delegate: self, queue: centralQueue) 
} 

// Rest of methods largely unchanged, although you should use `self.bleDevices` etc 

을 지금, 당신은 BLEDiscovery의 인스턴스를 할 때, 당신은 BLEDiscovery.sharedInstance 예를 들어, 사용할 수 있습니다

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    print("MainViewController :: didSelectRowAtIndexPath :: Row :: ", deviceTableView.indexPathForSelectedRow?.row) 

    let bleDiscovery = BLEDiscovery.sharedInstance 

    let peripheral = bleDiscovery.bleDevices[indexPath.row] 

    switch peripheral.state{ 

    case .Connected: 
     //Disconnect as device is connected 
     bleDiscovery.disconnectBLEDevice(peripheral) 
    case .Disconnected: 
     //Connect as device as disconnected 
     bleDiscovery.connectBLEDevice(peripheral) 

    default: break 

    } 

} 
+0

의견에 감사드립니다. 오늘 나중에 추천을 업데이트하고 테스트 해 보겠습니다. 당신은 큰 도움을주었습니다. 나는 무엇이 잘못되었지만 그것을 볼 수 없었던 것인지를 개념적으로 알았습니다 ... – user5308141

+0

또 하나의 질문으로, BLEDiscovery에 대한 대의원이되는 데 영향을 미칠까요? – user5308141

+0

예, 대리인과 싱글 톤은 좋은 조합이 아닙니다. 나는 NSNotification을 당신이 어떤 수의 가입자도 사용할 수 있기 때문에 사용할 것입니다. – Paulw11

관련 문제