pill_tracker/PillTracker/PillTracker/SimpleBluetoothIO.swift
2021-01-21 12:09:25 +00:00

126 lines
4.5 KiB
Swift

//
// SimpleBluetoothIO.swift
// PillTracker
//
// Created by Max Hunt on 16/01/2021.
//
import CoreBluetooth
protocol SimpleBluetoothIODelegate: class {
func simpleBluetoothIO(simpleBluetoothIO: SimpleBluetoothIO, didReceiveValue value: Int8)
func simpleBluetoothIO(simpleBluetoothIO: SimpleBluetoothIO, didConnect value: Bool)
func simpleBluetoothIO(simpleBluetoothIO: SimpleBluetoothIO, didDisconnect value: Bool)
}
class SimpleBluetoothIO: NSObject {
let serviceUUID: String
weak var delegate: SimpleBluetoothIODelegate?
var centralManager: CBCentralManager!
var connectedPeripheral: CBPeripheral?
var targetService: CBService?
var writableCharacteristic: CBCharacteristic?
var connected = false
init(serviceUUID: String, delegate: SimpleBluetoothIODelegate?) {
self.serviceUUID = serviceUUID
self.delegate = delegate
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func writeValue(value: Int8) {
guard let peripheral = connectedPeripheral, let characteristic = writableCharacteristic else {
return
}
let data = Data.dataWithValue(value: value)
peripheral.writeValue(data, for: characteristic, type: .withResponse)
}
}
extension SimpleBluetoothIO: CBCentralManagerDelegate {
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
self.connected = true
print("Connected! With \(String(describing: peripheral.name))")
delegate?.simpleBluetoothIO(simpleBluetoothIO: self, didConnect: true)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
connectedPeripheral = peripheral
if (peripheral.name != "[TV] Samsung Q7 Series (55)" && peripheral.name != "MacDeMax"){
print("Discovered \(String(describing: peripheral.name))")
}
if (peripheral.name != nil) {
if(((peripheral.name?.contains("PILL_TRACKER"))!))
{
if let connectedPeripheral = connectedPeripheral {
connectedPeripheral.delegate = self
centralManager.connect(connectedPeripheral, options: nil)
}
centralManager.stopScan()
}
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
// centralManager.scanForPeripherals(withServices: [CBUUID(string: serviceUUID)], options: nil)
centralManager.scanForPeripherals(withServices: nil, options: nil)
}
}
}
extension SimpleBluetoothIO: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else {
return
}
targetService = services.first
if let service = services.first {
targetService = service
peripheral.discoverCharacteristics(nil, for: service)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else {
return
}
for characteristic in characteristics {
if characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) {
writableCharacteristic = characteristic
}
peripheral.setNotifyValue(true, for: characteristic)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
guard let data = characteristic.value, let delegate = delegate else {
return
}
delegate.simpleBluetoothIO(simpleBluetoothIO: self, didReceiveValue: data.int8Value())
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
print("Disconnected: \(String(describing: peripheral.name))")
print("Restarting scan...")
centralManager.scanForPeripherals(withServices: nil, options: nil)
delegate?.simpleBluetoothIO(simpleBluetoothIO: self, didDisconnect: true)
}
}