// ViewController.swift import UIKit import CoreBluetooth import os class ViewController: UIViewController { /// https://qiita.com/eKushida/items/def628e0eff6c106d467 var serviceUUID : CBUUID! var characteristicUUID : CBUUID! var responseCharacteristicUUID : CBUUID! var centralManager: CBCentralManager! var peripheral: CBPeripheral! var writeCharacteristic: CBCharacteristic! var responsCharacteristic: CBCharacteristic! var data = Data() @IBOutlet weak var dispLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() setup() dispLabel.text = "Startup" } /// Initialize the central manager and UUID private func setup() { // Create an object representing the UUID. self.serviceUUID = CBUUID(string: "XXXXX0000-XXXX-XXXX-XXXX-XXXXXXXXXX") self.characteristicUUID = CBUUID(string: "XXXX2001-XXXX-XXXX-XXXX-XXXXXXXXXXXX") self.responseCharacteristicUUID = CBUUID(string: "XXXX2000-XXXX-XXXX-XXXX-XXXXXXXXXXXX") } /// Pairing process @IBAction func scan(_ sender: UIButton) { print("Pairing process") dispLabel.text = "Pairing process pressed" self.centralManager = CBCentralManager(delegate: self, queue: nil) } /// Communication connection @IBAction func connect(_ sender: UIButton) { print("Communication connection") /// https://qiita.com/MashMorgan/items/32500f158cb08d565786 /// https://knkomko.hatenablog.com/entry/2019/07/16/013443 let message = "**COMMAND**" let command = message + "\r" let writeData = Data(command.utf8) print("writeData:" + String(data: writeData, encoding: .utf8)!) peripheral.writeValue(writeData, for: writeCharacteristic, type: CBCharacteristicWriteType.withResponse) } } //MARK : - CBCentralManagerDelegate extension ViewController: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { //wait for power on and scan case CBManagerState.poweredOn: let services: [CBUUID] = [serviceUUID] ///serviceUUID centralManager.scanForPeripherals(withServices: nil, options: nil) // centralManager.scanForPeripherals(withServices: services, options: nil) print("isScanning:" + String(centralManager.isScanning)) default: break } } /// Called when a peripheral is discovered func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { self.peripheral = peripheral print("peripheral.name:" + String(peripheral.name ? "") + " peripheral.id:" + peripheral.identifier.uuidString) if "XXXXXXX" == peripheral.name { //start connection self.centralManager.connect(self.peripheral, options: nil) //peripheral is found, stop scanning centralManager.stopScan() } } /// called when connected func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { print("Connection successful serviceUUID:" + serviceUUID.uuidString) peripheral.delegate = self peripheral.discoverServices([serviceUUID]) dispLabel.text = "Peripheral connection successful" } /// Called when the connection fails func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { print("Connection failed") } /// When disconnected func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { print("Disconnection: \(String(describing: error))") } } //MARK : - CBPeripheralDelegate extension ViewController: CBPeripheralDelegate { /// Called when the characteristic is found func peripheral(_ peripheral: CBPeripheral, DidDiscoverCharacteristicsFor service: CBService, error: Error?) { if error ! = nil { print(error.debugDescription) return } guard let serviceCharacteristics = service.characteristics else { // error handling return } // Processing by characteristic for characreristic in serviceCharacteristics { if characreristic.uuid == characteristicUUID { // keep the characteristic for writing data self.writeCharacteristic = characreristic print("Write characreristic / UUID:" + characreristic.uuid.uuidString) print("Write characreristic / properties: \(self.writeCharacteristic.properties)") continue } if characreristic.uuid == responseCharacteristicUUID { peripheral.setNotifyValue(true, for: characreristic) self.responsesCharacteristic = characreristic print("Responses characreristic / UUID:" + characreristic.uuid.uuidString) print("Responses characreristic / properties: \(self.responsesCharacteristic.properties)") continue } print("Other characreristic / UUID:" + characreristic.uuid.uuidString) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverIncludedServicesFor: CBService, error: Error?){ print("peripheral didDiscoverIncludedServicesFor") } /// When writing data to the characteristic (called when sending a command) func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { print("peripheral didWriteValueFor") guard error == nil else { print("Error when writing characteristic data: \(String(describing: error))") // failure handling return } print(characteristic.value) } func peripheral(peripheral: CBPeripheral, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print("peripheral didUpdateNotificationStateForCharacteristic") if let error = error { print("Notify state update failed.... .error: \(error)") } else { print("Notify state update succeeded! isNotifying: \(characteristic.isNotifying)") } } func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print("peripheral didUpdateValueForCharacteristic") if let error = error { print("Data update notification error: \(error)") return } print("Data update! value: \(characteristic.value)") } /// When changing the characteristic func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { print("peripheral didUpdateValueFor") guard error == nil else { print("Error getting/changing characteristic value: \(String(describing: error))") // failure handling return } guard let data = characteristic.value else { print("characteristic.value") // failure process return } // data will be passed to us print(data) } func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { print("didUpdateNotificationStateFor") print(characteristic) } }