3

I'm trying to access a motion sensor (IMU sensor) via BLE. The structure is to connect/pair the sensor in one view controller and modify its settings, then to access and analyse its output data in another view controller (they are not segue connected).

How can I continue to access the data from the sensor that has been connected in another view controller? Coredata won't be ideal since it is real time presenting and the raw data is not needed to record. I can't pass the data through segue neither since they are not segue connected (they are accessed through different tab bar view controllers).

I found one link saying that it is possible to put the CBCentralManager etc into AppDelegate and then it becomes a central manager property (How to continue BLE activities onto next view controller). Is this the proper way to do it? If so, what part of the central manager should be put into AppDelegate?

Here is my code including searching for and build bluetooth connection.

var cManager = CBCentralManager()
var peripheralManager = CBPeripheralManager()

func centralManagerDidUpdateState(central: CBCentralManager!) {

    var message: String = ""
    switch cManager.state {

    case .PoweredOff:
        println("CoreBluetooth BLE hardware is powered off")

        let alertView = UIAlertController(title: "", message: "Please enable Bluetooth to start the measurement", preferredStyle: .Alert)
        alertView.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
        presentViewController(alertView, animated: true, completion: nil)

        break
    case .PoweredOn:
        println("CoreBluetooth BLE hardware is powered on and ready")

        self.scanForWAX9(self)
        break
    case .Resetting:
        println("CoreBluetooth BLE hardware is resetting")
        break
    case .Unauthorized:
        println("CoreBluetooth BLE state is unauthorized")
        break
    case .Unknown:
        println("CoreBluetooth BLE state is unknown")
        break
    case .Unsupported:
        println("CoreBluetooth BLE hardware is unsupported on this platform")
        break
    default:
        break
    }

}

func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) {

    println(peripheral.name);


    //************************************************************************************
    // Add some specification for bluetooth device
    //************************************************************************************

    if (peripheral.name != nil ) && (peripheral.name.rangeOfString("WAX9") != nil) {

        central.connectPeripheral(peripheral, options: nil)

        self.connectedPeripheral = peripheral

        println("PERIPHERAL NAME: \(peripheral.name)\n AdvertisementData: \(advertisementData)\n RSSI: \(RSSI)\n")

        println("UUID DESCRIPTION: \(peripheral.identifier.UUIDString)\n")

        println("IDENTIFIER: \(peripheral.identifier)\n")

        cManager.stopScan()
    }
}

@IBOutlet var connectNotice: UILabel!



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

    peripheral.delegate = self
    peripheral.discoverServices(nil)

    // self.connectedPeripheral = peripheral

    connectNotice.text = "\(peripheral.name) connected."
    connectNotice.textColor = UIColor.whiteColor()
    connectNotice.backgroundColor = UIColor(red:0.03, green:0.37, blue:0.5, alpha:0.5)

    cManager.stopScan()
    println("Scanning stopped")
    println("Connected to peripheral")
}



// Alert message when fail to connect, e.g. when sensor goes out of range
func centralManager(central: CBCentralManager!, didFailToConnectPeripheral peripheral: CBPeripheral!, error: NSError!) {
    println("FAILED TO CONNECT \(error)")

    let alertView = UIAlertController(title: "", message: "Failed to connect.", preferredStyle: .Alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
    presentViewController(alertView, animated: true, completion: nil)

    self.disconnect()
}

// Start to scan for sensor when disconnected
func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) {


    println("Disconnected from peropheral")
    let alertView = UIAlertController(title: "", message: "The connection is stopped.", preferredStyle: .Alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
    presentViewController(alertView, animated: true, completion: nil)

    self.connectedPeripheral = nil
    if scanAfterDisconnecting {
        scanForWAX9(self)
    }

}


func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager!) {

    switch peripheralManager.state {

    case .PoweredOff:
        println("Peripheral - CoreBluetooth BLE hardware is powered off")
        break

    case .PoweredOn:
        println("Peripheral - CoreBluetooth BLE hardware is powered on and ready")
        break

    case .Resetting:
        println("Peripheral - CoreBluetooth BLE hardware is resetting")
        break

    case .Unauthorized:
        println("Peripheral - CoreBluetooth BLE state is unauthorized")
        break

    case .Unknown:
        println("Peripheral - CoreBluetooth BLE state is unknown")
        break

    case .Unsupported:
        println("Peripheral - CoreBluetooth BLE hardware is unsupported on this platform")
        break
    default:
        break
    }

}

func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) {

    if (error != nil) {
        println("ERROR: \(error)")
        disconnect()
        return
    }

    for service in peripheral.services
    {
        NSLog("Discovered service: \(service.UUID)")

        peripheral.discoverCharacteristics(nil, forService: service as CBService)

    }
}
Community
  • 1
  • 1
Lynn_Yang
  • 157
  • 1
  • 11
  • The idea behind putting the CBCentralManager as a property accessible in the AppDelegate, is to use the fact that the AppDelegate is a sharedInstance (singleton pattern). But that's giving too much unrelated work to the AppDelegate. Let the AppDelegate do its jobs of "AppDelegating". Create yourself a Singleton (look on "Singleton + Swift") that will manage all of you BLE stuff. – Larme Apr 12 '17 at 08:43
  • Thank you so much! – Lynn_Yang Apr 29 '17 at 13:53

1 Answers1

2

You could possibly create a global class that can become the central manager property?

See this answer how to do that: https://stackoverflow.com/a/6067515/1331332

You could then use NSNotificationCenter to send the data throughout your app, just set up the observers in each ViewController

Community
  • 1
  • 1
mhorgan
  • 886
  • 2
  • 11
  • 32