Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- JPA
- FLUTTER
- Git
- Code
- Realm
- IOS
- SwiftUI
- mac
- Session
- rxswift
- appstore
- Notification
- Apple
- window
- 개발자
- stack
- 웹뷰
- 한글
- error
- Firebase
- Swift
- Archive
- iOS16
- Python
- Xcode
- MacOS
- darkmode
- github
- UIButton
- view
Archives
- Today
- Total
EEYatHo 앱 깎는 이야기
Swift ) Core Location Monitor 소개 본문
반응형
샘플앱 링크 (Xcode16, iOS18 이상 필요)
개요
- 새로운 CLMonitor API의 소개
- 단순하면서 강력한 Monitoring 기능을 코드 몇줄로 작성 가능
let self.monitor = await CLMonitor("iHeartMonitor")
await self.monitor.add(aConfition, identifier: "Work")
Task {
for try await event in self.monitor.events {
takeAction(on: event))
}
}
Monitor overview (모니터 개요)
- 사용자의 위치나 비컨을 모니터링하는 새로운 방식
- CLMonitor은 Swift의 최상위 액터
- 각 CLMonitor 인스턴스는, 모니터링의 게이트웨이가 됨
- 액터이기에, 스레드와 작업 동기화 오버헤드를 거치지 않음
- CLMonitor 콘텐츠에 접근하거나 조건을 추가, 제거할 때는 await를 사용
- 모니터 인스턴스 생성시 식별자(영숫자열) 필요
- 같은 이름의 모니터가 없다면, 새로운 모니터 인스턴스 생성
- 같은 이름의 모니터가 있다면, 기존의 모니터 인스턴스 반환
- 모니터링 조건도 식별자 사용
- 모니터 인스턴스에 모니터링할 조건을 추가하며, 추가 메서드를 이용해 식별자와 연동할 수 있음
- 아래 그림처럼 “Work”라는 식별자를 이용하여, 사용자가 근무중일 때 기록한 조건들 식별가능
- 기록과 콘텐츠는 식별자를 통해 접근 가능
- 모니터링은 조건이 삭제되기 전까지 가능
- 조건을 삭제하면, 관련 기록도 함께 삭제
Supported Conditions (지원하는 조건들)
- 모니터링 조건의 추가와 제거 방법
- iOS에서 지원하는 조건에는 두가지가 있음.
- CircularGeographicConfition
- 중심(위도,경도)과 반경(미터)으로 정의
- iOS 16 이하의 CLCircularRegoin과 비슷
- 영역을 안 = 조건 충족, 영역 밖 = 조건 불충족
- 여기서도 radius가 100이네.. 100이 최소인건가? 언급은 없음
- BeaconIdentityCondition
- CLBeaconIdentityConstraint와 비슷
- iOS 16 이하의 CLBeaconRegion과도 비슷
- 비콘기기를 이용해 상당히 정확한 위치를 파악가능
- Beacon
- UUID문자열, major, minor 로 식별 (UUID 하나만 사용해도 가능)
- 3개를 모두 앎으로써 정확한 위치(비콘) 파악
- 애플 구내식당 예시
- 식당들은 모두 같은 UUID 사용 (건물식당과 공원식당)
- major로 어떤 식당인지 구분 (공원식당)
- minor로 식당 내에 어디에 있는지 구분 (디저트, 한식 등)
- 조건 입력하기
- 위에서 생성한 조건을 모니터에 식별자와 함께 add
- 이미 있는 식별자를 add할 경우, 새로 입력된 조건으로 대체됨
- 조건의 초기상태는 CoreLocation이 확인하기 전까지는 미정(unknowed)
- 조건을 추가하기 전에, 어떤 상태인지 알고 있다면 조건의 기본상태를 재정의 하면됨
- add시, assuming: .unsatisfied를 할경우 불충족 상태에서 모니터링이 시작됨
Inspecting Records
- 모니터링 기록에 담기는 콘텐츠와, 앱 수명주기 동안 기록에 접근하는 방법
- 기록을 생성하면 모두 앱에 저장됨
- 기록은 조건과 이벤트를 가짐
- 이벤트는 상태(충,불충,미정), 조건이 상태값에 이른 날짜 및 시간, 조건(refinement)를 가짐
- major, minor 조건이 충족된 이벤트는 해당 major, minor값을 가진 refinement와 함께 생성됨
- 충족되지 않은 이벤트는 refinement가 nil (?? 그냥 이벤트자체가 없어야하는거 아닌가)
- 기록 인스턴스는 여러개일 수 있음
- 각 기록은 조건의 식별자로 구분됨
- 기록은 조건과 lastEvents식별자와 함께 모두 앱에 저장됨
- 마지막으로 관찰된 조건과 이에 따른 상태를 언제든지 조회할 수 있음
let monitoredRecord = await self.monitor.record(for: "conditionId") let condition = monitoredRecord?.condition // 조건 확인 let lastEvent = monitoredRecord?.lastEvent // 이벤트 학인, 원한다면 여기서 Date까지 let lastState = lastEvent?.state // 상태값 확인
- 입력한 조건으로 기록된게 없으면 nil
- 모든 기록을 확인하는 방법
- 모니터에 조건 식별자 목록(identifiers)이 있기에, for돌려서 조회가능
Handling Events
- 모니터링 중인 조건에 이벤트가 발생했을 때, 앱에서 어떤 조치를 취해야하는가
- CoreLocation이 모니터링한 조건의 상태가, lastEvent의 상태와 다르면, CoreLocation은 monitor.events라는 비동기 시퀀스 프로퍼티를 통해 새로운 이벤트를 전송함
- state를 가지고 충,불충,미정을 확인
- event의 id값으로 직전 기록을 조회가능 → 조건이 변경되기 까지 얼마나 시간이 걸렸는지 확인가능
let self.monitor = await CLMonitor("iHeartMonitor")
await self.monitor.add(aConfition, identifier: "Work")
Task {
for try await event in self.monitor.events {
if let record = await self.monitor.record(for: event.identifier) {
let lastEvent = record.lastEvent
let duration = lastEvent.date.timeIntervalSinceNow // 직전 이벤트와 지금 시간을 비교. 단위 = 초
}
}
}
Best practices
- CLMonitor 사용에 도움이되는 요구사항과 팁들
- 여러 조건을 분리하기 위해 여러 모니터를 사용해도 되지만, 식별자 하나로는 하나만 모니터를 인스턴스화 해야합니다.
- CLMonitor은 모니터링 중인 조건의 상태를 유지하기 때문에, 같은 이름으로 다른 작업을 시작하면 예상치 못한 동작이 일어날 수 있음
- 예상치 못한 이벤트가 있을 수 있으니, 항상 모니터의 이벤트 시퀀스에 Task를 대기시키는게 좋습니다.
- 이벤트가 특정 기록의 lastEvent로 바뀌려면, 반드시 사용자의 처리가 필요
- 이벤트 대기중이 아닐 때, 조건의 상태가 바뀐다면, 직접 반영하기 전에는 모니터에 반영되지 않음
- 앱이 종료된 상태일 때, 모니터링 중인 조건에 이벤트가 발생했을 때, CoreLocation은 백그라운드에서 앱을 실행함
- 사용자의 위치 수신 권한이 있을 때만 가능
- 앱이 실행될 때 마다 모니터를 재활성화하고, 이벤트를 기다려야한다는 뜻
- 그래야만 모니터링 중인 조건의 상태를 확인할 수 있음
- 이때 필요한 것이 didFinishLauncingWithOptions 메소드
- CLMonitor은 Launching Behavior이기에, 앱에서만 사용하길 권장
- 위젯이나 플러그인에서 사용해도 앱이 실행되어서, 단일 이름, 단일 모니터 규칙이 무너질 수 있음
- 조건과 상태는 유지됨
- 이벤트는 CLMonitor가 모니터링 중인 조건에서 변화가 관찰되었을 때 발생함
- 이 상태를 여러분의 테이블 안에 두기보다는, CLMonitor가 보여주는대로 보실 것을 강력히 권장
- 다만 SwiftUI visualization같은 일부 응용 프로그램은 별도의 표현을 필요로할 수 있음
- 그럴때는 예상되는 이벤트 추론 대신, SwiftUI를 위해 표현을 남겨두세요
맺음말
- 꼭 사용해보세요. 모니터링 경험이 크게 향상될 것임
- 예시 프로젝트 존재
- 위치 업데이트 세션도 추천샘플앱 링크 (Xcode16, iOS18 이상 필요)
'iOS, Swift > Geofencing' 카테고리의 다른 글
Swift ) 지리적 지역 근접성 Monitoring (1) | 2024.11.01 |
---|
Comments