EEYatHo 앱 깎는 이야기

Swift ) Core Location Monitor 소개 본문

iOS, Swift/Geofencing

Swift ) Core Location Monitor 소개

EEYatHo 2024. 11. 1. 18:32
반응형

영상 링크

샘플앱 링크 (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에서 지원하는 조건에는 두가지가 있음.
  1. CircularGeographicConfition
    • 중심(위도,경도)과 반경(미터)으로 정의
    • iOS 16 이하의 CLCircularRegoin과 비슷
    • 영역을 안 = 조건 충족, 영역 밖 = 조건 불충족
    • 여기서도 radius가 100이네.. 100이 최소인건가? 언급은 없음
  2. 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