Notice
Recent Posts
Recent Comments
Link
투케이2K
112. (ios/swift) 비콘 목록 다중 스캔 실시 - beacon list multi scan 본문
[개발 환경 설정]
개발 툴 : XCODE
개발 언어 : SWIFT
[방법 설명]
[소스 코드]
/*
MARK: - [실시간 비콘 스캔 요약 설명]
// -----------------------------------------
[필요한 import 선언]
import CoreLocation
import CoreBluetooth
*/
// -----------------------------------------
/*
[필요한 class delegate 선언]
class A_Main: UIViewController, CLLocationManagerDelegate { }
*/
// -----------------------------------------
/*
[실시간 비콘 스캔 시작 방법]
self.startBeaconScanFlag = true // 비콘 스캔 시작 플래그 지정
self.checkLocationPermission() // 위치 권한 확인 >> 비콘 스캔 시작
*/
// -----------------------------------------
/*
[실시간 비콘 스캔 종료 방법]
self.beaconScanTimerStop()
*/
// -----------------------------------------
/*
[실시간 비콘 스캔 로직]
Function [권한 확인] : checkLocationPermission
Function [권한 체크] : locationManager [didChangeAuthorization]
Function [스캔 시작] : beaconScanStart / beaconScanTimerStart
Function [스캔 목록 확인] : locationManager [didRangeBeacons]
*/
// -----------------------------------------
// MARK: - [실시간 비콘 스캐닝을 위한 전역 변수 선언 부분]
// -----------------------------------------
var locationManager : CLLocationManager! // [위치 권한 상태 확인]
// -----------------------------------------
var startBeaconScanFlag = false // [비콘 스캔 시작 여부 확인 플래그]
// -----------------------------------------
var beaconScanCount = 1 // [비콘 스캔 진행 카운트 값]
let beaconScanCountMax = 13 // [비콘 스캔 진행 최대값 정의]
// -----------------------------------------
var beaconScanTimer : Timer? // [실시간 비콘 스캔 진행 여부 확인 타이머 핸들러]
// -----------------------------------------
//var scanUuid = UUID(uuidString: "F7A3E806-F5BB-43F8-BA87-0783669EBEB1")! // MARK: [단일 :: 비콘 스캔 Uuid :: 필수 설정]
let scanUuid = [UUID(uuidString: "F7A3E806-F5BB-43F8-BA87-0783669EBEB1")!,
UUID(uuidString: "F7A3E806-F5BB-43F8-BA87-0783669EBEB2")!] // MARK: [다중 :: 비콘 스캔 Uuid :: 필수 설정]
// -----------------------------------------
//var scanMajor = 1 // [비콘 스캔 Major :: 필요시 추가 설정]
//var scanMinor = 121 // [비콘 스캔 Minor :: 필요시 추가 설정]
// -----------------------------------------
var scanBeaconRegion: CLBeaconRegion! // [실시간 비콘 스캔 감지 : 특정 uuid 일치값 설정]
// -----------------------------------------
var scanBeaconRegionConstraints: Any? = nil // [비콘 스캔 RegionConstraints]
// -----------------------------------------
// MARK: - [위치 권한 활성 상태 확인 : 비콘 스캔]
func checkLocationPermission() {
DispatchQueue.main.async {
print("")
print("===============================")
print("[A_Main >> checkLocationPermission() :: [위치 사용 권한 요청 실시]]")
print("===============================")
print("")
// -----------------------------------------
self.locationManager = CLLocationManager.init() // [locationManager 초기화]
self.locationManager.delegate = self // [델리게이트 넣어줌]
self.locationManager.requestAlwaysAuthorization() // [위치 권한 설정 값을 받아옵니다]
// -----------------------------------------
self.locationManager.startUpdatingLocation() // [위치 업데이트 시작]
// -----------------------------------------
}
}
// MARK: [위치 서비스에 대한 권한 확인 실시]
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [위치 사용 권한 확인 실시]]")
print("===============================")
print("")
// -----------------------------------------
if status == .authorizedAlways {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [위치 사용 권한 항상 허용]]")
print("===============================")
print("")
// [비콘 스캔 플래그 값 확인]
if startBeaconScanFlag == true {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [authorizedAlways] :: [beaconScanStart]]")
print("===============================")
print("")
// [실시간 비콘 스캔 시작]
self.beaconScanStart()
}
}
// -----------------------------------------
if status == .authorizedWhenInUse {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [위치 사용 권한 앱 사용 시 허용]]")
print("===============================")
print("")
// [비콘 스캔 플래그 값 확인]
if startBeaconScanFlag == true {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [authorizedWhenInUse] :: [beaconScanStart]]")
print("===============================")
print("")
// [실시간 비콘 스캔 시작]
self.beaconScanStart()
}
}
// -----------------------------------------
if status == .denied {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [위치 사용 권한 거부]]")
print("===============================")
print("")
// [비콘 스캔 플래그 값 확인]
if startBeaconScanFlag == true {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [denied] :: [startBeaconScanFlag == false]]")
print("===============================")
print("")
// [비콘 스캔 플래그 변경]
self.startBeaconScanFlag = false
}
}
// -----------------------------------------
if status == .restricted || status == .notDetermined {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [위치 사용 권한 대기 상태]]")
print("===============================")
print("")
// [비콘 스캔 플래그 값 확인]
if startBeaconScanFlag == true {
print("")
print("===============================")
print("[A_Main >> locationManager() :: [restricted || notDetermined] :: [startBeaconScanFlag == false]]")
print("===============================")
print("")
// [비콘 스캔 플래그 변경]
self.startBeaconScanFlag = false
}
}
// -----------------------------------------
}
// MARK: - [실시간 비콘 스캐닝 진행]
func beaconScanStart() {
// -----------------------------------------
// [플래그 값 초기 지정]
self.startBeaconScanFlag = false
// -----------------------------------------
// [이미 비콘 스캔이 진행 중인 경우 먼저 종료 위함]
self.beaconScanTimerStop()
// -----------------------------------------
// [비콘 스캔 카운트 초기화]
self.beaconScanCount = 1
// -----------------------------------------
// [비콘 스캔 진행 실시]
if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
if CLLocationManager.isRangingAvailable() { // [비콘 스캔 기능을 이용할 수 있는 경우]
print("")
print("===============================")
print("[A_Main >> beaconScanStart() :: 실시간 비콘 스캔 실시 [정상]]")
print("설 명 :: CLLocationManager.isRangingAvailable == true]")
print("===============================")
print("")
if #available(iOS 13, *) {
// -----------------------------------------
// MARK: [단일 지정]
// [사용 셋팅 : 특정 uuid 일치 값 설정]
//self.scanBeaconRegion = CLBeaconRegion.init(uuid: self.scanUuid, identifier: self.scanUuid.uuidString)
//self.scanBeaconRegionConstraints = CLBeaconIdentityConstraint(uuid: self.scanUuid)
// [비콘 스캔 시작]
//self.locationManager.startMonitoring(for: self.scanBeaconRegion)
//self.locationManager.startRangingBeacons(satisfying: self.scanBeaconRegionConstraints as! CLBeaconIdentityConstraint)
// -----------------------------------------
// MARK: [다중 지정]
// [for 문 사용해서 비콘 스캔 값 추가 실시]
for i in stride(from: 0, through: self.scanUuid.count-1, by: 1) {
self.scanBeaconRegion = CLBeaconRegion.init(uuid: self.scanUuid[i], identifier: self.scanUuid[i].uuidString)
self.scanBeaconRegionConstraints = CLBeaconIdentityConstraint(uuid: self.scanUuid[i])
self.locationManager.startMonitoring(for: self.scanBeaconRegion)
self.locationManager.startRangingBeacons(satisfying: self.scanBeaconRegionConstraints as! CLBeaconIdentityConstraint)
}
// -----------------------------------------
}
else {
// -----------------------------------------
// MARK: [단일 지정]
// [사용 셋팅 : 특정 uuid 일치 값 설정]
//self.scanBeaconRegion = CLBeaconRegion.init(proximityUUID: self.scanUuid, identifier: self.scanUuid.uuidString)
// [비콘 스캔 시작]
//self.locationManager.startMonitoring(for: self.scanBeaconRegion)
//self.locationManager.startRangingBeacons(in: self.scanBeaconRegion)
// -----------------------------------------
// MARK: [다중 지정]
// [for 문 사용해서 비콘 스캔 값 추가 실시]
for i in stride(from: 0, through: self.scanUuid.count-1, by: 1) {
self.scanBeaconRegion = CLBeaconRegion.init(proximityUUID: self.scanUuid[i], identifier: self.scanUuid[i].uuidString)
self.locationManager.startMonitoring(for: self.scanBeaconRegion)
self.locationManager.startRangingBeacons(in: self.scanBeaconRegion)
}
// -----------------------------------------
}
// -----------------------------------------
// [비콘 스캔 시작 플래그 값 지정]
self.startBeaconScanFlag = true // [비콘 스캔 시작 플래그 변경]
self.beaconScanTimerStart() // [타이머 시작 호출]
// -----------------------------------------
}
else {
print("")
print("===============================")
print("[A_Main >> beaconScanStart() :: 실시간 비콘 스캔 실시 [비정상]]")
print("설 명 :: CLLocationManager.isRangingAvailable == false]")
print("===============================")
print("")
// -----------------------------------------
// [비콘 스캔 시작 플래그 변경]
self.startBeaconScanFlag = false
// -----------------------------------------
}
}
else {
print("")
print("===============================")
print("[A_Main >> beaconScanStart() :: 실시간 비콘 스캔 실시 [비정상]]")
print("설 명 :: CLLocationManager.isMonitoringAvailable == false]")
print("===============================")
print("")
// -----------------------------------------
// [비콘 스캔 시작 플래그 변경]
self.startBeaconScanFlag = false
// -----------------------------------------
}
}
// MARK: - [실시간 비콘 감지 수행 부분]
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
if beacons.count > 0 { // [스캔된 비콘 개수가 있는 경우 : UUID]
// [for 반복문을 수행하면서 스캔한 비콘 정보 확인 실시]
for beacon in beacons {
// -----------------------------------------
var SCAN_UUID = ""
if #available(iOS 13, *) {
SCAN_UUID = String(beacon.uuid.uuidString) // uuid 값
}
else {
SCAN_UUID = String(beacon.proximityUUID.uuidString) // uuid 값
}
// -----------------------------------------
let SCAN_MINOR : String = String(beacon.minor.description) // minor 값
let SCAN_MAJOR : String = String(beacon.major.description) // major 값
// -----------------------------------------
print("")
print("===============================")
print("[A_Main >> didRangeBeacons() :: 실시간 비콘 스캔 세부 정보]")
print("beacon [uuid] :: ", SCAN_UUID)
print("beacon [minor] :: ", SCAN_MINOR)
print("beacon [major] :: ", SCAN_MAJOR)
print("beacon [rssi] :: ", beacon.rssi)
print("===============================")
print("")
// -----------------------------------------
}
}
}
// MARK: - [실시간 비콘 스캐닝 종료]
func beaconScanStop(){
print("")
print("===============================")
print("[A_Main >> beaconScanStop() :: 실시간 비콘 스캔 종료]")
print("===============================")
print("")
// -----------------------------------------
// [비콘 변수 값 초기화 부분]
self.beaconScanCount = 1 // 비콘 스캔 카운트 초기화
self.startBeaconScanFlag = false // 비콘 스캔 플래그 변경
// -----------------------------------------
// MARK: [단일 지정]
// [비콘 스캔 모니터링 종료]
/*
self.locationManager.stopMonitoring(for: self.scanBeaconRegion)
// [비콘 범위 감지 종료]
if #available(iOS 13, *) {
self.locationManager.stopRangingBeacons(satisfying: self.scanBeaconRegionConstraints as! CLBeaconIdentityConstraint)
}
else {
self.locationManager.stopRangingBeacons(in: self.scanBeaconRegion)
}
*/
// -----------------------------------------
// MARK: [다중 지정]
// [for 문 사용해서 비콘 스캔 제거 실시]
for i in stride(from: 0, through: self.scanUuid.count-1, by: 1) {
self.scanBeaconRegion = CLBeaconRegion.init(proximityUUID: self.scanUuid[i], identifier: self.scanUuid[i].uuidString)
// [비콘 스캔 모니터링 종료]
self.locationManager.stopMonitoring(for: self.scanBeaconRegion)
// [비콘 범위 감지 종료]
if #available(iOS 13, *) {
self.scanBeaconRegionConstraints = CLBeaconIdentityConstraint(uuid: self.scanUuid[i])
self.locationManager.stopRangingBeacons(satisfying: self.scanBeaconRegionConstraints as! CLBeaconIdentityConstraint)
}
else {
self.locationManager.stopRangingBeacons(in: self.scanBeaconRegion)
}
}
// -----------------------------------------
}
// MARK: - [비콘 스캔 실시간 반복 작업 시작 호출]
func beaconScanTimerStart(){
print("")
print("===============================")
print("[A_Main >> beaconScanTimerStart() :: 비콘 스캔 타이머 동작 [시작]]")
print("===============================")
print("")
// -----------------------------------------
// [타이머 객체 생성 실시 :: 주기 timeInterval = 1초]
self.beaconScanTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.beaconScanTimerCallback), userInfo: nil, repeats: true)
// -----------------------------------------
}
// [실시간 반복 작업 수행 부분]
@objc func beaconScanTimerCallback() {
print("")
print("===============================")
print("[A_Main >> beaconScanTimerCallback() :: 비콘 스캔 타이머 동작 [진행]]")
print("비콘 스캔 카운트 :: \(self.beaconScanCount)")
print("===============================")
print("")
// [처리할 로직 작성 실시]
self.beaconScanCount += 1 // [1씩 카운트 값 증가 실시]
if self.beaconScanCount > self.beaconScanCountMax { // [카운트 값이 max 보다 큰 경우]
// -----------------------------------------
self.beaconScanTimerStop() // [타이머 종료 실시]
// -----------------------------------------
}
}
// [실시간 반복 작업 정지 호출]
func beaconScanTimerStop(){
print("")
print("===============================")
print("[A_Main >> beaconScanTimerStop() :: 비콘 스캔 타이머 동작 [종료]]")
print("===============================")
print("")
// [실시간 반복 작업 중지]
if self.beaconScanTimer != nil && self.beaconScanTimer!.isValid {
// -----------------------------------------
self.beaconScanTimer!.invalidate() // [타이머 초기화]
// -----------------------------------------
self.beaconScanStop() // [비콘 스캔 종료 호출]
// -----------------------------------------
}
}
[결과 출력]
반응형
'IOS' 카테고리의 다른 글
114. (ios/swift) wkwebview 웹뷰 스크롤 바운스 방지 실시 (0) | 2022.02.03 |
---|---|
113. (ios/swift) 테스트 플라이트 (TestFlight) 내부 테스트 계정 추가 방법 (0) | 2022.02.03 |
111. (ios/swift) Transporter 트랜스 포터 사용해 업로드한 ipa 파일 앱 스토어 에서 업데이트 실시 (0) | 2022.01.31 |
110. (ios/swift) 앱 스토어 리젝 (reject) 해결 - background audio service (백그라운드 오디오 서비스) (0) | 2022.01.30 |
109. (ios/swift) 사진 찍기 카메라 (camera) 호출 수행 실시 - UIImagePickerController (0) | 2022.01.27 |
Comments