Core Bluetooth Background Processing for iOS Apps
앱은 포그라운드와 백그라운드에서 다르게 동작되어야 한다. 왜냐하면 iOS 디바이스에서는 시스템 리소스의 제한이 있기 때문이다. 일반적인 블루투스의 작동방식은 앱이 백그라운드/Suspended 상태로 갔을 때 중앙장치나 주변장치 모두 disabled처리 되는 것이다.
그 말은 즉 앱에 코어 블루투스 백그라운드 실행 모드를 살려서 앱을 깨우거나 할 수 있다는 것이다. 백그라운드 프로세싱 전부를 지원하지는 못하더라도 시스템이 여전히 어떤 중요한 이벤트가 일어났다고는 알려줄 수 있다.
만약 앱이 코어 블루투스 백그라운드 실행 모드를 지원한다면, 이 앱은 계속 실행시킬 수 없다. 어떤 지점에서 시스템은 앱을 종료해서 메모리 해제를 해줘서 현재 포그라운드에서 작동되는 앱을 실행가능하도록 해야하기 때문이다. 그래서 펜딩이라던지 활성화된 연결이 없어질수가 있다. iOS7 부터 코어 블루투스는 중앙장치와 주변장치의 상태를 저장하는 것을 지원한다. 그리고 앱이 실행되면 이 상태를 다시 저장한다. 이 기능을 활용해서 블루투스 디바이스를 활용한 롱텀 실행이 가능할 것이다.
Foreground-Only Apps
대부분의 iOS 앱들은 백그라운드 스테이트를 가면 suspended state로 변경된다. 특정 태스크를 백그라운드에 돌리겠다고 권한을 받지 않을 경우에 말이다. 서스펜디드 상태에서는 다시 포그라운드로 돌아오기 전까지는 블루투스 관련된 태스크를 진행할 수 없다. 혹은 어떤 블루투스 관련된 이벤트를 진행할 수 없다.
중앙장치 사이드에서는 포그라운드 앱(즉, 백그라운드 실행모드를 선언하지 않은 앱)에서는 백그라운드나 서스펜드 상태에서 scan 처리또한 할 수 없다. 주변장치에서는 advertising 자체가 작동불가하며 그 어떤 중앙장치가 앱의 퍼블리쉬된 서비스의 characterisitc 값에 접근하려고 하면 error를 받는다.
사용자 케이스에 따라 이러한 일반적 행동은 앱의 여러방향으로 영향을 줄 수 있다. 예를 들면 사용자가 현재 연결된 주변장치와 인터렉팅 하고싶을 때. 또는, 앱이 서스펜디드 스테이트로 갔을 때(유저가 다른 앱으로 전환해서). 만약 앱이 서스펜드 상태에서 주변장치와의 연결이 끊어진다해도 다시 앱을 켜는 순간까지 장치와의 연결이 끊어졌다는 사실을 알 수 다.
Take Advantage of Peripheral Connection Options
포그라운드에서만 작동되는 앱에서는 서스펜디드 스테이트에 갔을 때 블루투스 관련 이벤트들은 시스템에 의해 queue 되어지고, 앱이 다시 포그라운드 작업으로 갔을 때 실행이 된다. 코어블루투스는 유저에게 이벤트를 알릴 수 있는 방법을 제공하는데, 이를 이용해서 포그라운드로 이벤트들을 가져올건지 정하면 된다.
아래 CBCentralManager 클래스에 있는 주변장치 연결 관련 메소드들을 이용하면 된다.
- CBConnectPeripheralOptionNotifyOnConnectionKey—Include this key if you want the system to display an alert for a given peripheral if the app is suspended when a successful connection is made.
앱은 서스펜드 스테이트 상태인데, 주어진 주변장치와의 연결이 성공적으로 되었을 때 알림창을 준다.
- CBConnectPeripheralOptionNotifyOnDisconnectionKey—Include this key if you want the system to display a disconnection alert for a given peripheral if the app is suspended at the time of the disconnection.
앱이 서스펜드 스테이트 상태인데, 주변장치와의 연결이 끊어졌을 때 연결해제되었다는 알림창을 준다.
- CBConnectPeripheralOptionNotifyOnNotificationKey—Include this key if you want the system to display an alert for all notifications received from a given peripheral if the app is suspended at the time.
앱이 서스펜드 스테이트 상태인데 주변장치로부터 받은 모든 노티피케이션을 알림창으로 주고싶을 때이다.
Core Bluetooth Background Execution Modes
만약 백그라운드도 블루투스 관련 테스크들이 동작하도록 하려면?
1. info.plist에 정의한다.
이때 앱은 서스펜디드 상태에서 일어나 블루투스 관련된 이벤트들을 처리할 수 있도록 해준다. 이러한 지원은 심박수 모니터와 같은 앱, 일정한 간격으로 데이터를 전달하는 BLE 디바이스와 소통할 때 중요하다.
나의 앱이 central의 장치를 하는지 peripheral의 역할을 하는지에 따라 info.plist에 정의하는 값은 달라진다.
- bluetooth-central—The app communicates with Bluetooth low energy peripherals using the Core Bluetooth framework.
- bluetooth-peripheral—The app shares data using the Core Bluetooth framework.
하지만 백그라운드로 돌리더라도 제약사항이 너무 많다.
- 시스템의 상황에 따라서 앱이 백그라운드에 실행이 되지 않을수도 있고,, 복잡한 수행은 할 수 없고 간단한 통신값 저장 정도할 수 있으며 10초 이내에 종료되는 작업이여야 한다.
The bluetooth-central Background Execution Mode
위와 같이 info.plist에 장치 특성에 따라 값을 저장해주면 이제 앱에서 블루투스관련된 태스크를 백그라운드로 도릴 수 있다. 백그라운드에 있더라도 주변장치를 스캔하거나 데이터를 가지고 상호작용할 수 있다. 그리고 시스템이 앱을 꺠운다. CBCentralManagerDelegate or CBPeripheralDelegate delegate 관련 메소드들이 발동될 때마다! 이를 통해서 중앙장치의 중요한 이벤트들이 핸들링 가능하다. 센트럴매니저의 상태값이 변경된다던지, characterisic value가 변동된다던지 하는 것들을 모두 포착할 수 있다.
주의 사항으로는 백그라운드에서 스캔을 진행할 시에 스캔 옵션키로 정해놓은 디바이스만 찾아지는게 아니라 모든 디바이스가 다 찾아진다는 점이다. 또한, 중앙장치가 광고 패킷을 스캔하는 인터벌이 길어진다. 그래서 주변장치를 발견하는 시간이 길어진다.
Use Background Execution Modes Wisely
백그라운드 실행모드를 현명하게 쓰는 것이 중요하다. 디바이스의 배터리 수명을 위해서 백그라운드에서 하는 작업은 최소화 하자. 그리고 아래와 같은 3가지 가이드라인을 따르자.
1. 앱은 세션 베이스여야 한다. 유저가 블루투스 이벤트를 언제 시작하고 끝마칠지에 대한 인터페이스를 제공해야한다.
2. 앱이 백그라운드에서 깨어있는 동안 10초 이내로 태스크가 완수되어야 한다. 다시 서스펜드 모드로 갈 수 있도록 가장 빠르게 테스크를 완수 해야한다. 백그라운드에서 너무 길게 실행되는 테스크가 있다면 앱이 kill될 것이다.
3. 앱은 원래 목적을 떠나 상관없는 과한 태스크를 진행하지 않도록 해야한다.
Core Bluetooth Background Processing for iOS Apps
Core Bluetooth Background Processing for iOS Apps For iOS apps, it is crucial to know whether your app is running in the foreground or the background. An app must behave differently in the background than in the foreground, because system resources are mor
developer.apple.com
앱의 생명주기 참고
- Background : 앱 사용중에 다른 앱을 실행하거나 홈 화면으로 나갔을 때 상태입니다. 백그라운드에서 동작하는 코드를 추가하면 suspended 상태로 넘어가지 않고 백그라운드 상태를 유지하게 됩니다. 처음부터 background 상태로 실행되는 앱은 inactive 대신 background 상태로 진입합니다. 음악을 실행하고 홈 화면으로 나가도 음악이 나오는 상태가 이 경우에 해당됩니다.
- Suspended : 앱이 background 상태에서 추가적인 작업을 하지 않으면 곧바로 suspended 상태로 진입합니다. 앱을 다시 실행할 경우 빠른 실행을 위해 메모리에만 올라가 있습니다. 메모리가 부족한 상황이 되면 iOS는 suspended 상태에 있는 앱들을 메모리에서 해제시켜서 메모리를 확보합니다.
'[iOS] App Development' 카테고리의 다른 글
[iOS] App 배포 관련 내용: 라이센스, 배포 순서 (0) | 2022.11.15 |
---|---|
[iOS 오류] M1에서 Firebase빌드시 나타나는 오류 / Apple M1 Cocoapod 사용시 주의점 / FIRAnalyticsConnector' for architecture arm64 (0) | 2022.05.28 |
[iOS] 회원탈퇴 기능 추가시 유의사항, UserDefault - get, set, remove, 삭제여부확인 (0) | 2022.01.30 |
[iOS] 비동기 프로그래밍 : Sync, Async, Concurrent, Serial (0) | 2022.01.26 |
[iOS] FireStore에서 데이터 정렬하기 : 쿼리방법(order by), 내림차순 (2) | 2022.01.08 |