투케이2K

614. (ios/swift5) [유틸 파일] observableBluetoothScanList : 블루투스 실시간 리스트 목록 스캔 수행 본문

IOS

614. (ios/swift5) [유틸 파일] observableBluetoothScanList : 블루투스 실시간 리스트 목록 스캔 수행

투케이2K 2024. 12. 25. 10:08

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT5

 

[소스 코드]

 

// --------------------------------------------------------------------------------------
[개발 및 테스트 환경]
// --------------------------------------------------------------------------------------

- 언어 : Swift

- 개발 툴 : Xcode

- 기술 구분 : CoreBluetooth / CBCentralManagerDelegate

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[사전) 의존성 설정 및 퍼미션 권한 설정 정리]
// --------------------------------------------------------------------------------------

  /**
    * // ------------------------------------------------------------
    * 1. 필요 퍼미션 권한 설정 : 블루투스 사용 권한
    * // ------------------------------------------------------------
    * - Privacy - Bluetooth Always Usage Description
    * - Privacy - Bluetooth Peripheral Usage Description
    * // ------------------------------------------------------------
    * 2. 필요 import 호출 선언 :
    * // ------------------------------------------------------------
    * - import CoreBluetooth
    * - import UIKit
    * // ------------------------------------------------------------
    * */

// --------------------------------------------------------------------------------------







// --------------------------------------------------------------------------------------
[소스 코드]
// --------------------------------------------------------------------------------------

// -------------------------------------------------------
// MARK: - [전역 변수 선언]
// -------------------------------------------------------
public static let ACTIVITY_NAME = "C_Bluetooth_Module"






// -------------------------------------------------------
// MARK: - [SEARCH FAST] : observableBluetoothScanList : 블루투스 실시간 목록 스캔 결과 반환
// -------------------------------------------------------
// [필요 info plist / import 및 delegate]
// -------------------------------------------------------
/*
// [필요 info plist]
Privacy - Bluetooth Always Usage Description
Privacy - Bluetooth Peripheral Usage Description

// [필요 import 및 delegate]
import CoreBluetooth / CBCentralManagerDelegate / CBPeripheralManagerDelegate
*/
// -------------------------------------------------------
// [소스 코드 사용 방법]
// -------------------------------------------------------
/*
C_Bluetooth_Module().observableBluetoothScanList(){(result) in
          
    S_Log._D_(description: "실시간 블루투스 리스트 스캔 결과", data: ["\(result)"])
    
}
*/
// -------------------------------------------------------

var scanBluetoothList: Array<Dictionary<String, String>> = []
private let scanBluetoothOperationQueue = OperationQueue() // [블루투스 스캔 작업 큐 정의]
public static let BLE_SCAN_TIME_OUT = 10.0 // [블루투스 스캔 타임 아웃 시간]
var scanBluetoothCentralManager: CBCentralManager! // [블루투스 활성 상태 확인 및 실시간 블루투스 신호 스캔]

func observableBluetoothScanList(callback: @escaping (Array<Dictionary<String, String>>) -> ()) {
    S_Log._D_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: observableBluetoothScanList :: 실시간 블루투스 리스트 스캔 실시", data: nil)
    

    // ---------------------------------------------
    // [초기 값 초기화]
    // ---------------------------------------------
    self.scanBluetoothList = []
    
    
    // ---------------------------------------------
    // [작업 큐에 추가]
    // ---------------------------------------------
    self.scanBluetoothOperationQueue.isSuspended = true
    let block = { callback(self.scanBluetoothList) }
    self.scanBluetoothOperationQueue.addOperation(block)
    
    
    // ---------------------------------------------
    // [비동기 작업 수행 실시]
    // ---------------------------------------------
    DispatchQueue.main.async {
      
        // [실시간 블루투스 권한 확인]
        self.scanBluetoothCentralManager = CBCentralManager(delegate: self, queue: nil)
        
    }
    
}






// -------------------------------------------------------
// MARK: - [블루투스 권한 부여 상태 응답 확인] : CBCentralManagerDelegate : Delegate
// -------------------------------------------------------
func centralManagerDidUpdateState(_ central: CBCentralManager) {
    
    switch central.state {

    // ---------------------------------------------------------
    case .unknown:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: unknown :: 블루투스 상태 알수 없음", data: nil)

        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
    // ---------------------------------------------------------

    case .resetting:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: resetting :: 블루투스 서비스 리셋", data: nil)
        
        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
    // ---------------------------------------------------------
    case .unsupported:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: unsupported :: 기기가 블루투스를 지원하지 않습니다", data: nil)
        
        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
    // ---------------------------------------------------------
    case .unauthorized:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: unauthorized :: 블루투스 사용 권한 확인 필요", data: nil)
        
        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
        
        // MARK: [앱 블루투스 권한 사용 설정창 이동 및 확인 필요]
    // ---------------------------------------------------------
    case .poweredOff:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: poweredOff :: 블루투스 비활성 상태", data: nil)
        
        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
        
        // MARK: [자동으로 시스템에서 비활성 상태 알림 및 팝업창 호출 실시]
    // ---------------------------------------------------------
    case .poweredOn:
        S_Log._W_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: poweredOn :: 블루투스 활성 상태", data: nil)
        
        // ---------------------------------------------------------
        // MARK: [블루투스 실시간 스캔 시작] : centralManager : didDiscover : 함수에서 확인
        // ---------------------------------------------------------
        if self.scanBluetoothCentralManager != nil {
            self.scanBluetoothCentralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey:false])
        }


        // MARK: [타이머 동작 : 특정 시간 이후 스캔 종료 처리]
        DispatchQueue.main.asyncAfter(deadline: .now() + C_Bluetooth_Module.BLE_SCAN_TIME_OUT) { // [스캔 종료 타임 아웃 지정]
            if self.scanBluetoothCentralManager != nil {
                S_Log._D_(description: "\(C_Beacon_Client_Module.ACTIVITY_NAME) :: poweredOn :: 블루투스 스캔 타임 아웃 완료", data: nil)
                
                // [블루투스 스캔 종료]
                self.scanBluetoothCentralManager?.stopScan()


                // [블루투스 스캔 리스트 콜백 반환]
                self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]

            }
        }

    // ---------------------------------------------------------
    @unknown default:
        S_Log._E_(description: "\(C_Bluetooth_Module.ACTIVITY_NAME) :: 블루투스 권한 :: default :: 상태", data: nil)
        
        self.scanBluetoothOperationQueue.isSuspended = false // [블루투스 스캔 큐 해제]
    }
    // ---------------------------------------------------------
}






// -------------------------------------------------------
// MARK: - [블루투스 장치를 찾았을 때 실행되는 이벤트] : CBCentralManagerDelegate : didDiscover
// -------------------------------------------------------
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
    print("\(C_Bluetooth_Module.ACTIVITY_NAME) :: didDiscover :: 실시간 블루투스 스캔 정보 확인 >> NAME - \(String(peripheral.name ?? "")) / UUID - \(String(peripheral.identifier.uuidString)) / RSSI - \(String(RSSI.intValue))")


    // -------------------------------------------------
    // [특정 UUID 를 찾은 경우 : 샘플 코드]
    // -------------------------------------------------
    // if String(peripheral.identifier.uuidString).contains("DB809C5F-9598-16BA-563B-E329FDFA17A3") == true { }
    

    // -------------------------------------------------
    // MARK: [스캔 리턴 리스트에 저장]
    // -------------------------------------------------
    var bleScanDic : Dictionary<String, String> = [String : String]()
    bleScanDic["NAME"] = "\(String(peripheral.name ?? ""))"
    bleScanDic["UUID"] = "\(String(peripheral.identifier.uuidString))"
    bleScanDic["RSSI"] = "\(String(RSSI.intValue))"

    if self.scanBluetoothList != nil {
        self.scanBluetoothList.append(bleScanDic) // [배열에 추가]
    }

}

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[결과 출력]
// --------------------------------------------------------------------------------------

================================================================
LOG :: TYPE :: LOG :: 🟢
-------------------------------------------------
LOG :: CLASS PLACE :: A_Webview.swift :: testMain() :: 1458
-------------------------------------------------
LOG :: DESCRIPTION :: 실시간 블루투스 리스트 스캔 결과
-------------------------------------------------
LOG :: [["UUID": "BF0DD758-765E-701A-D277-1DFF17EE5559", "RSSI": "-52", "NAME": ""], ["NAME": "2K", "RSSI": "-93", "UUID": "F7C9845E-F074-53BA-3745-6C763A25CDC7"]]
================================================================

// --------------------------------------------------------------------------------------

 

반응형
Comments