왕논의 연구실

CoreBluetooth 본문

iOS/Swift

CoreBluetooth

ywangnon 2025. 4. 3. 23:37

🔷 CoreBluetooth란?

CoreBluetooth는 iOS/macOS/watchOS에서 BLE(Bluetooth Low Energy) 기기와 통신하기 위한 프레임워크
BLE는 저전력 특성을 가지며, 스마트워치, 센서, 피트니스 기기 등에 주로 사용

CoreBluetooth는 다음 두 가지 역할을 제공

  1. Central: 주변 BLE 기기(Peripheral)를 검색하고 연결 → 일반적인 iOS 앱은 이 역할.
  2. Peripheral: 데이터를 송신하거나 알림을 보내는 기기 → iOS도 Peripheral 역할이 가능하지만 흔치 않음.

📡 기본 개념

용어 설명
CBCentralManager BLE 스캔과 연결을 담당하는 객체
CBPeripheral 연결된 BLE 기기
CBService Peripheral이 제공하는 기능 묶음
CBCharacteristic 실제 데이터 송수신이 이루어지는 속성
CBDescriptor Characteristic의 부가 정보

🧭 BLE 연결의 전체 흐름 (iOS 앱 기준, Central 역할)

  1. Central Manager 초기화
    CBCentralManager(delegate:queue:)로 시작 → centralManagerDidUpdateState(_:) 호출됨
    여기서 BLE가 켜져 있는지 확인 (.poweredOn)

  2. 🔍 BLE 기기 스캔
    centralManager.scanForPeripherals(withServices:options:)
    발견되면 didDiscover peripheral 호출됨

  3. 🔗 기기 연결 시도
    centralManager.connect(peripheral, options:)
    성공 시 didConnect peripheral 호출됨

  4. 🔍 Service 검색
    peripheral.discoverServices(nil)
    didDiscoverServices 호출됨

  5. 🔍 Characteristic 검색
    peripheral.discoverCharacteristics(nil, for: service)
    didDiscoverCharacteristicsFor service 호출됨

  6. 📤 데이터 송신
    peripheral.writeValue(_:for:type:)
    .withResponse or .withoutResponse로 설정 가능

  7. 📥 데이터 수신 (알림 구독)
    peripheral.setNotifyValue(true, for: characteristic)
    데이터 오면 didUpdateValueFor characteristic 호출


✍️ 기본 사용 예시 (중심 흐름)

// 1. 초기화
let centralManager = CBCentralManager(delegate: self, queue: nil)

// 2. 상태 업데이트
func centralManagerDidUpdateState(_ central: CBCentralManager) {
    if central.state == .poweredOn {
        central.scanForPeripherals(withServices: [serviceUUID])
    }
}

// 3. 기기 발견
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi: NSNumber) {
    self.peripheral = peripheral
    central.connect(peripheral, options: nil)
}

// 4. 연결 성공
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    peripheral.delegate = self
    peripheral.discoverServices(nil)
}

// 5. 서비스 검색
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    if let service = peripheral.services?.first {
        peripheral.discoverCharacteristics(nil, for: service)
    }
}

// 6. Characteristic 발견
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    if let characteristic = service.characteristics?.first {
        self.characteristic = characteristic

        // 알림 구독
        peripheral.setNotifyValue(true, for: characteristic)

        // 데이터 전송 예
        let data = "Hello".data(using: .utf8)!
        peripheral.writeValue(data, for: characteristic, type: .withResponse)
    }
}

// 7. 데이터 수신
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if let data = characteristic.value {
        print("수신 데이터: \(data)")
    }
}

🛠️ 실전 팁

항목 설명
권한 설정 Info.plist에 NSBluetoothAlwaysUsageDescription 추가
백그라운드 지원 bluetooth-central background mode 설정 필요
기기 필터링 peripheral의 name 또는 advertisementData 확인
보안 통신 인증된 characteristic 필요할 수 있음 (예: .encrypted)

🧠 외워야 할 delegate 흐름 요약

centralManagerDidUpdateState → scanForPeripherals
→ didDiscover → connect → didConnect
→ discoverServices → didDiscoverServices
→ discoverCharacteristics → didDiscoverCharacteristics
→ setNotifyValue / writeValue → didUpdateValue

✅ 핵심 요약

  • CBCentralManager로 BLE 시작
  • 상태 → 검색 → 연결 → 서비스 → characteristic → 송수신
  • delegate 흐름을 따라가면 자연스럽게 구성 가능
  • 블루투스 관련 설정은 Info.plist + Background Mode 고려 필요

'iOS > Swift' 카테고리의 다른 글

CAEmitterLayer  (0) 2025.04.12
OSLog 요소  (0) 2025.04.11
Apple API Guidelines - Naming  (0) 2025.03.19
Coordinator 패턴 + Factory 패턴  (0) 2025.03.19
의존성 역전 원칙(DIP)이란?  (0) 2025.03.17