How to maintain the Bluetooth by using Swift5

Hello, I am a beginner at Swift. I am having trouble maintaining the Bluetooth connection between the Adafruit Esp32 Feather and iPhones. I used Xcode and Swift5 to develop an iOS application. The problem is that when I leave the scene that includes Bluetooth code and returns to the previous scene, Bluetooth will automatically disconnect from the iPhone. I have to power off and on the Adafruit Esp32 Feather board, and tap the device button on the history view controller scene to connect to Bluetooth again. This makes the user experience very inconvenient. How can I keep the Bluetooth connection, even after I leave this page? In this way, I don't have to close and open the Adafruit Esp32 Feather board every time I leave this scene and want to enter this scene again.
Below is the Bluetooth code:

import Foundation
import CoreBluetooth
 
var manager:CBCentralManager?
var myPeripheral:CBPeripheral?
var myCharacteristic:CBCharacteristic?
let serviceUUID = [```]
 
 
final class BleManager: NSObject, ObservableObject, CBCentralManagerDelegate {
    public var UserDeviceName = ""
    public var connectedText = ""
 
    struct DeviceInfo {
        let DeviceName: String
        let serviceUUID: String
        let peripheralUUID: String
    }
    
var UserDevice: [DeviceInfo] = [```]
    
    override init() {
        super.init()
        manager = CBCentralManager(delegate: self, queue: nil)
        manager?.delegate = self
        }
    
    func startScanning() {
        manager?.stopScan()
        manager?.scanForPeripherals(withServices: serviceUUID, options: nil)
    }
    
    func sendText(text: String) {
            if (myPeripheral != nil && myCharacteristic != nil) {
                let data = text.data(using: .utf8)
                myPeripheral!.writeValue(data!,  for: myCharacteristic!, type: CBCharacteristicWriteType.withResponse)
            }
        }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        for DeviceInfo in UserDevice {
            if peripheral.identifier.uuidString == DeviceInfo.peripheralUUID {
                myPeripheral = peripheral
                myPeripheral?.delegate = self
                manager?.connect(myPeripheral!, options: nil)
                UserDeviceName = DeviceInfo.DeviceName
                manager?.stopScan()
            }
        }
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
            switch central.state {
            case .poweredOff:
                print("Bluetooth is switched off")
            case .poweredOn:
                print("Bluetooth is switched on")
            case .resetting:
                print("resetting")
            case .unauthorized:
                print("unauthorized")
            case .unsupported:
                print("Bluetooth is not supported")
            case .unknown:
                print("Unknown state")
            @unknown default:
                fatalError()
            }
        }
    
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        peripheral.discoverServices(serviceUUID)
        connectedText = "\(UserDeviceName) has connected"
        print("Connected to " +  peripheral.name!)
       }
    
    public func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
        if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] {
            peripherals.forEach { (awakedPeripheral) in
                print(". - Awaked peripheral \(String(describing: awakedPeripheral.name))")
                guard let localName = awakedPeripheral.name,
                localName == UserDeviceName else {
                    return
                }
                
                myPeripheral = awakedPeripheral
            }
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("Disconnected from " +  peripheral.name!)
        }
    
    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
            print(error!)
        }
}
 
extension BleManager: CBPeripheralDelegate {
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
            guard let services = peripheral.services else { return }
            
            for service in services {
                peripheral.discoverCharacteristics(nil, for: service)
            }
        }
        
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
            guard let characteristics = service.characteristics else { return }
            myCharacteristic = characteristics[0]
        }
}

To keep the Bluetooth connection you must probably guarantee the survival of the BleManager after you established a connection because it contains both the instances for the Central and the Peripheral.
To guarantee that there are plenty of solutions, the faster is to implement a singleton another one is to inject the BluetoothManager to all the subsequent "scene" once you established a connection.

Terms of Service

Privacy Policy

Cookie Policy