Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //This is the BLE Central Class
- import Foundation
- import UIKit
- import CoreBluetooth
- var txCharacteristic : CBCharacteristic?
- var rxCharacteristic : CBCharacteristic?
- var blePeripheral : CBPeripheral?
- var characteristicASCIIValue = NSString()
- class BLECentralViewController : UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UITableViewDelegate, UITableViewDataSource{
- //Data
- var centralManager : CBCentralManager!
- var RSSIs = [NSNumber]()
- var data = NSMutableData()
- var writeData: String = ""
- var peripherals: [CBPeripheral] = []
- var characteristicValue = [CBUUID: NSData]()
- var timer = Timer()
- var characteristics = [String : CBCharacteristic]()
- //UI
- @IBOutlet weak var baseTableView: UITableView!
- @IBOutlet weak var refreshButton: UIBarButtonItem!
- @IBAction func refreshAction(_ sender: AnyObject) {
- disconnectFromDevice()
- self.peripherals = []
- self.RSSIs = []
- self.baseTableView.reloadData()
- startScan()
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- self.baseTableView.delegate = self
- self.baseTableView.dataSource = self
- self.baseTableView.reloadData()
- centralManager = CBCentralManager(delegate: self, queue: nil)
- let backButton = UIBarButtonItem(title: "Disconnect", style: .plain, target: nil, action: nil)
- navigationItem.backBarButtonItem = backButton
- }
- override func viewDidAppear(_ animated: Bool) {
- disconnectFromDevice()
- super.viewDidAppear(animated)
- refreshScanView()
- print("View Cleared")
- }
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
- print("Stop Scanning")
- centralManager?.stopScan()
- }
- /*Okay, now that we have our CBCentalManager up and running, it's time to start searching for devices. You can do this by calling the "scanForPeripherals" method.*/
- func startScan() {
- peripherals = []
- print("Now Scanning...")
- self.timer.invalidate()
- centralManager?.scanForPeripherals(withServices: [BLEService_UUID] , options: [CBCentralManagerScanOptionAllowDuplicatesKey:false])
- Timer.scheduledTimer(timeInterval: 17, target: self, selector: #selector(self.cancelScan), userInfo: nil, repeats: false)
- }
- /*We also need to stop scanning at some point so we'll also create a function that calls "stopScan"*/
- func cancelScan() {
- self.centralManager?.stopScan()
- print("Scan Stopped")
- print("Number of Peripherals Found: (peripherals.count)")
- }
- func refreshScanView() {
- baseTableView.reloadData()
- }
- //-Terminate all Peripheral Connection
- /*
- Call this when things either go wrong, or you're done with the connection.
- This cancels any subscriptions if there are any, or straight disconnects if not.
- (didUpdateNotificationStateForCharacteristic will cancel the connection if a subscription is involved)
- */
- func disconnectFromDevice () {
- if blePeripheral != nil {
- // We have a connection to the device but we are not subscribed to the Transfer Characteristic for some reason.
- // Therefore, we will just disconnect from the peripheral
- centralManager?.cancelPeripheralConnection(blePeripheral!)
- }
- }
- func restoreCentralManager() {
- //Restores Central Manager delegate if something went wrong
- centralManager?.delegate = self
- }
- func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,advertisementData: [String : Any], rssi RSSI: NSNumber) {
- blePeripheral = peripheral
- self.peripherals.append(peripheral)
- self.RSSIs.append(RSSI)
- peripheral.delegate = self
- self.baseTableView.reloadData()
- if blePeripheral == nil {
- print("Found new pheripheral devices with services")
- print("Peripheral name: (String(describing: peripheral.name))")
- print("**********************************")
- print ("Advertisement Data : (advertisementData)")
- }
- }
- //Peripheral Connections: Connecting, Connected, Disconnected
- //-Connection
- func connectToDevice () {
- centralManager?.connect(blePeripheral!, options: nil)
- }
- //-Connected
- func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
- print("*****************************")
- print("Connection complete")
- print("Peripheral info: (String(describing: blePeripheral))")
- //Stop Scan- We don't need to scan once we've connected to a peripheral. We got what we came for.
- centralManager?.stopScan()
- print("Scan Stopped")
- //Erase data that we might have
- data.length = 0
- //Discovery callback
- peripheral.delegate = self
- //Only look for services that matches transmit uuid
- peripheral.discoverServices([BLEService_UUID])
- //Once connected, move to new view controller to manager incoming and outgoing data
- let storyboard = UIStoryboard(name: "Main", bundle: nil)
- let firstVC = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
- firstVC.peripheral = peripheral
- navigationController?.pushViewController(firstVC, animated: true)
- }
- func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
- if error != nil {
- print("Failed to connect to peripheral")
- return
- }
- }
- func disconnectAllConnection() {
- centralManager.cancelPeripheralConnection(blePeripheral!)
- }
- func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
- print("*******************************************************")
- if ((error) != nil) {
- print("Error discovering services: (error!.localizedDescription)")
- return
- }
- guard let services = peripheral.services else {
- return
- }
- //We need to discover the all characteristic
- for service in services {
- peripheral.discoverCharacteristics(nil, for: service)
- // bleService = service
- }
- print("Discovered Services: (services)")
- }
- func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
- print("*******************************************************")
- if ((error) != nil) {
- print("Error discovering services: (error!.localizedDescription)")
- return
- }
- guard let characteristics = service.characteristics else {
- return
- }
- print("Found (characteristics.count) characteristics!")
- for characteristic in characteristics {
- //looks for the right characteristic
- if characteristic.uuid.isEqual(BLE_Characteristic_uuid_Rx) {
- rxCharacteristic = characteristic
- //Once found, subscribe to the this particular characteristic...
- peripheral.setNotifyValue(true, for: rxCharacteristic!)
- // We can return after calling CBPeripheral.setNotifyValue because CBPeripheralDelegate's
- // didUpdateNotificationStateForCharacteristic method will be called automatically
- peripheral.readValue(for: characteristic)
- print("Rx Characteristic: (characteristic.uuid)")
- }
- if characteristic.uuid.isEqual(BLE_Characteristic_uuid_Tx){
- txCharacteristic = characteristic
- print("Tx Characteristic: (characteristic.uuid)")
- }
- peripheral.discoverDescriptors(for: characteristic)
- }
- }
- func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
- if characteristic == rxCharacteristic {
- if let ASCIIstring = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) {
- characteristicASCIIValue = ASCIIstring
- print("Value Recieved: ((characteristicASCIIValue as String))")
- NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Notify"), object: nil)
- }
- }
- }
- func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
- print("*******************************************************")
- if error != nil {
- print("(error.debugDescription)")
- return
- }
- if ((characteristic.descriptors) != nil) {
- for x in characteristic.descriptors!{
- let descript = x as CBDescriptor!
- print("function name: DidDiscoverDescriptorForChar (String(describing: descript?.description))")
- print("Rx Value (String(describing: rxCharacteristic?.value))")
- print("Tx Value (String(describing: txCharacteristic?.value))")
- }
- }
- }
- func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
- print("*******************************************************")
- if (error != nil) {
- print("Error changing notification state:(String(describing: error?.localizedDescription))")
- } else {
- print("Characteristic's value subscribed")
- }
- if (characteristic.isNotifying) {
- print ("Subscribed. Notification has begun for: (characteristic.uuid)")
- }
- }
- func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
- print("Disconnected")
- }
- func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
- guard error == nil else {
- print("Error discovering services: error")
- return
- }
- print("Message sent")
- }
- func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
- guard error == nil else {
- print("Error discovering services: error")
- return
- }
- print("Succeeded!")
- }
- //Table View Functions
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return self.peripherals.count
- }
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: "BlueCell") as! PeripheralTableViewCell
- let peripheral = self.peripherals[indexPath.row]
- let RSSI = self.RSSIs[indexPath.row]
- if peripheral.name == nil {
- cell.peripheralLabel.text = "nil"
- } else {
- cell.peripheralLabel.text = peripheral.name
- }
- cell.rssiLabel.text = "RSSI: (RSSI)"
- return cell
- }
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- blePeripheral = peripherals[indexPath.row]
- connectToDevice()
- }
- func centralManagerDidUpdateState(_ central: CBCentralManager) {
- if central.state == CBManagerState.poweredOn {
- // We will just handle it the easy way here: if Bluetooth is on, proceed...start scan!
- print("Bluetooth Enabled")
- startScan()
- } else {
- //If Bluetooth is off, display a UI alert message saying "Bluetooth is not enable" and "Make sure that your bluetooth is turned on"
- print("Bluetooth Disabled- Make sure your Bluetooth is turned on")
- let alertVC = UIAlertController(title: "Bluetooth is not enabled", message: "Make sure that your bluetooth is turned on", preferredStyle: UIAlertControllerStyle.alert)
- let action = UIAlertAction(title: "ok", style: UIAlertActionStyle.default, handler: { (action: UIAlertAction) -> Void in
- self.dismiss(animated: true, completion: nil)
- })
- alertVC.addAction(action)
- self.present(alertVC, animated: true, completion: nil)
- }
- }
- }
- //Now the FirstViewController
- class FirstViewController: UIViewController, UIPeripheralManagerDelegate {
- var peripheralManager: CBPeripheralManager?
- var peripheral: CBPeripheral!
- viewDidLoad(){
- //I'm calling the blePeripheral from BLE class to the peripheral in the current class
- peripheral = blePeripheral
- }
- //I have a button here to send some data and only when I receive the data I want to go to the next view controller
- @IBAction func login(_sender: AnyObject) {
- //This is my write code
- let bytes : [UInt8] = [ 0x1A, 0x2B, 0x3C, 0x4D ]
- let Transmitdata = NSData(bytes: bytes, length: bytes.count)
- peripheral.writeValue(Transmitdata as Data, for: txCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
- print("Data Sent",Transmitdata)
- //Give time for data to be received fromdevice
- sleep(1)
- //let ReceiveData = rxCharacteristic?.value
- if let ReceiveData = ReceiveData {
- let ReceivedNoOfBytes = ReceiveData.count
- var ReceivedByteArray = [UInt8](repeating: 0, count: ReceivedNoOfBytes)
- (ReceiveData as NSData).getBytes(&ReceivedByteArray, length: ReceivedNoOfBytes)
- print("Data Received ",ReceivedByteArray)
- //checking if we received the right data?
- if(ReceivedByteArray[0] == 10 && ReceivedByteArray[1] == 20 && ReceivedByteArray[2] == 30 && ReceivedByteArray[3] == 40){
- performSegue(withIdentifier: "Second_View", sender: self)
- }
- }
- }
- class SecondViewController: UIViewController{
- var firstview: FirstViewController?
- var peripheralManager: CBPeripheralManager?
- var peripheral: CBPeripheral!
- override func viewWillAppear(_animated: Bool){
- let peripheral = firstview?.peripheral
- let peripheralManager = firstview?.peripheralManager
- }
- //I have another button here to direct me to third view controller class
- @IBAction func mainmenu(_sender: AnyObject){
- //send some bytes
- //receiver some bytes
- //similar to the first view controller
- If correct data is received
- {
- performSegue(withIdentifier: "Main_M", sender: self)
- }
- }
- override func prepare(for segue: UIStoryboardSegue, sender: Any?){
- if segue.destination is Main_M
- {
- let gotoM = segue.destination as? Main_M
- gotoM?.peripheral = firstview?.peripheral
- }
- }
Add Comment
Please, Sign In to add comment