[swift] Swift Core Bluetooth를 활용한 스마트 도어록 시스템 개발

이번 프로젝트에서는 Swift Core Bluetooth 프레임워크를 사용하여 스마트 도어록 시스템을 개발하는 방법을 알아보겠습니다. 스마트 도어록은 앱을 통해 잠금 해제하거나 잠그는 기능을 제공하는 시스템으로, Bluetooth를 통해 도어록 장치와 통신합니다.

1. Bluetooth 연결 설정

스마트 도어록을 개발하기 위해 먼저 Bluetooth 연결을 설정해야 합니다. Core Bluetooth에서는 CBCentralManager를 사용하여 Bluetooth 장치를 스캔하고 연결할 수 있습니다.

import CoreBluetooth

class DoorLockManager: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager!

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            // Bluetooth가 활성화된 상태
            // 장치 스캔 및 연결 로직을 구현
        }
    }
}

위 코드에서는 DoorLockManager 클래스를 생성하고, CBCentralManagerDelegate를 채택하여 Bluetooth 연결 상태 변경에 대한 알림을 받습니다. centralManagerDidUpdateState 메서드에서 Bluetooth가 활성화된 경우, 장치 스캔 및 연결 로직을 구현할 수 있습니다.

2. 도어록 장치 스캔

Bluetooth가 활성화된 상태에서 도어록 장치를 스캔해야 합니다. Core Bluetooth에서는 CBCentralManager의 scanForPeripherals 메서드를 사용하여 장치를 스캔할 수 있습니다.

class DoorLockManager: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager!
    var doorLockPeripheral: CBPeripheral?

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            centralManager.scanForPeripherals(withServices: nil, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        // 스캔된 도어록 장치 발견 시 호출되는 메서드
        // 도어록 장치에 연결하는 로직 구현
    }
}

위 코드에서는 scanForPeripherals 메서드를 사용하여 도어록 장치를 스캔하고, 발견된 도어록 장치에 연결하는 로직을 구현해야 합니다. centralManager(_:didDiscover:advertisementData:rssi:) 메서드는 도어록 장치가 발견될 때 호출되며, 여기에서 연결하고자 하는 도어록 장치에 대한 로직을 추가할 수 있습니다.

3. 도어록 장치와 연결

도어록 장치를 스캔하고 발견한 후에는 해당 장치와의 연결을 설정해야 합니다. Core Bluetooth에서는 CBPeripheral의 connect 메서드를 사용하여 장치를 연결할 수 있습니다.

class DoorLockManager: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager!
    var doorLockPeripheral: CBPeripheral?

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            centralManager.scanForPeripherals(withServices: nil, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if peripheral.name == "DoorLockDevice" {
            doorLockPeripheral = peripheral
            centralManager.connect(doorLockPeripheral!, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        // 도어록 장치와 연결될 때 호출되는 메서드
        // 도어록 장치와의 통신을 설정하는 로직 구현
    }
}

위 코드에서는 스캔된 도어록 장치의 이름을 확인하여 선택한 장치와 연결하고, 연결된 장치와의 통신을 설정할 수 있습니다.

4. 도어록 잠금 해제

Bluetooth로 도어록 장치와 연결되었다면, 스마트 도어록에서 잠금을 해제하는 기능을 구현할 수 있습니다.

class DoorLockManager: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager!
    var doorLockPeripheral: CBPeripheral?
    var doorLockCharacteristic: CBCharacteristic?

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            centralManager.scanForPeripherals(withServices: nil, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if peripheral.name == "DoorLockDevice" {
            doorLockPeripheral = peripheral
            centralManager.connect(doorLockPeripheral!, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        doorLockPeripheral?.delegate = self
        doorLockPeripheral?.discoverServices(nil)
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if let services = peripheral.services {
            for service in services {
                doorLockPeripheral?.discoverCharacteristics(nil, for: service)
            }
        }
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if let characteristics = service.characteristics {
            for characteristic in characteristics {
                if characteristic.uuid == CBUUID(string: "DoorLockCharacteristicUUID") {
                    doorLockCharacteristic = characteristic
                }
            }
        }
    }

    func unlockDoor() {
        if let characteristic = doorLockCharacteristic {
            let unlockCommand: [UInt8] = [0x01, 0x02, 0x03, 0x04] // 예시 잠금 해제 명령
            let data = Data(unlockCommand)
            doorLockPeripheral?.writeValue(data, for: characteristic, type: .withResponse)
        }
    }
}

위 코드에서는 peripheral(:didDiscoverServices:) 메서드를 사용하여 도어록 장치의 서비스를 발견하고, peripheral(:didDiscoverCharacteristicsFor:error:) 메서드를 사용하여 도어록 장치의 특성을 발견합니다. unlockDoor() 메서드에서는 잠금 해제 명령을 만들어 도어록 장치에 전송합니다.

이제 Swift Core Bluetooth를 활용하여 스마트 도어록 시스템을 개발할 수 있습니다. 위 코드를 참고하여 기능을 확장하거나 추가할 수 있습니다.

참고 자료