스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
watchOS에서 Bluetooth 기기로부터 적시에 알림 수신
Bluetooth 기기에서 Apple Watch에 적절한 적시 알림을 보내는 방법을 확인하세요. 컴플리케이션에서 주기적 데이터를 활용하는 방법을 보여드리고, 백그라운드 주변 검색에 대해 살펴보며, watchOS에서 특성 모니터링을 사용하는 방법을 배워보겠습니다. 또한 우수한 Bluetooth 액세서리를 만들기 위한 모범 사례 및 디자인 지침을 소개합니다.
리소스
관련 비디오
WWDC21
-
다운로드
안녕하세요, 저는 Yann입니다 핵심 블루투스 엔지니어 이번에는 Apple Watch에서 블루투스 기기에 대한 적절한 알림에 대해 말씀드리겠습니다
먼저 WatchOS 앱이 백그라운드에 있을 때 컴플리케이션 업데이트 하는 법을 살펴보고 watchOS 앱에서
제때 알림을 받는 법에 대해 자세히 알아보겠습니다
그리고 watchOS 9에서 주변 장치를 발견하는 새 방법도 알아보겠습니다
마지막으로 여러분들의 블루투스 액세서리를 디자인하는 데 필요한 최적의 방법과 권장 사항을 말씀드리겠습니다
첫 번째 주제를 살펴보겠습니다 백그라운드에서 watchOS 앱의 컴플리케이션 업데이트 방법입니다 지난해에는 watchOS 8에서 백그라운드 앱 새로고침을 통해 블루투스 액세서리로 컴플리케이션을 업데이트 하는 법을 소개했습니다
이는 다음과 같이 현재 기온을 알려주는 것과 같이 주기적으로 업데이트되는 데이터에 적합합니다
지난 번엔 작년부터 watchOS를 통해 컴플리케이션 업데이트와 백그라운드상 주기적으로 실행되는 백그라운드 앱 새로고침을 사용할 수 있게 됐습니다 백그라운드 앱 새로고침을 할 때마다 블루투스 주변 장치에 다시 연결하게 되고 데이터를 수집한 뒤 주변 장치에서 연결을 끊습니다 자세한 내용은 'Connect Bluetooth devices to Apple Watch'를 시청해주세요
만약에 블루투스 주변 장치에서 사용자에게 빠르게 알려야 하는 경우에는 어떻게 해야할까요?
watchOS 9에서는 블루투스 액세서리로부터 백그라운드 상태에서 알림을 듣는 법이 도입됐습니다
작동 방식은 다음과 같습니다 앱이 실행 중일 때 기기를 연결하고 특성 모니터링을 시작합니다
앱 실행이 중지돼도 Core Bluetooth는 연결을 유지하고 특성에 변경이 생기는지를 기다리기 시작합니다
기기에서 해당 특성의 값이 변경되면 해당 이벤트를 처리하기 위해 앱에 런타임이 할당되어 로컬 알림을 보내거나 네트워크 요청 등을 보낼 수 있죠 이를 통해 사용자들이 빨리 알아야되는 정보들을 전달하도록 설계되었습니다
식품 온도계가 있다고 가정해 보겠습니다 원하는 조리 온도를 설정해 오븐에서 음식을 꺼내야 할 때 알림을 받을 수 있습니다
온도가 원하는 온도에 가까워지면 온도계는 특성 값을 변경하고 앱은 음식이 거의 준비되었다고 로컬 알림을 보냅니다
음식이 완료되면 알림을 받습니다
그리고 온도가 계속 올라가면 최후 알림을 받습니다
먼저 백그라운드 모드를 구성하는 법에 대해 살펴보겠습니다
Watch 앱의 Info.plist에 있는 UIBackgroundModes에 Bluetooth-central을 추가합니다
Xcode에서는 'Required background modes'라고 하며 'App communicates using CoreBluetooth'를 추가해야 합니다
백그라운드 실행을 중심으로 사용하려는 경우 이와 같은 Info.plist 항목은 iOS용 앱과 동일합니다
iOS 'Signing capabilities'에 의지하지 않고 watchApp info.plist를 수동으로 편집해야 할 수 있습니다
코드를 살펴보겠습니다 이미 연결되어 있다고 가정하고 GATT 서비스를 찾았습니다 그리고 곧 GATT 특성을 발견해 didDiscoverCharacteristicFor라는 콜백을 받게 됩니다
콜백 내부에서 값이 변경될 때마다 알림을 받도록 정할 수 있습니다
이는 watchOS 8과 동일한 API이지만 앱이 백그라운드에 있는 동안에도 작동한다는 차이점이 있습니다
그런 다음 didUpdateValueFor로 특성 값의 변경 사항을 처리하는 대리자 메서드를 구현합니다
특성이 변경되면 로컬 알림을 보내거나 네트워크 요청 등 앱에 적합한 어떤 것이든 보낼 수 있습니다 이 메서드는 앱이 실행중일때와 백그라운드일 때 모두 호출되므로 따라서 두 경우 다 올바른 작업을 수행하도록 만들어야 합니다
이제 고려해봐야 할 몇 가지 상황에 대해 이야기해 보겠습니다
먼저 블루투스 재연결에 대해 생각해봅시다 장치가 범위를 벗어나면 블루투스 연결이 시간 초과 후 연결이 끊어집니다
이 경우에는 바로 앱이 백그라운드 런타임을 받아 'connectPeripheral'을 호출해 재연결을 시도하기 위합니다 이는 iOS에서와 동일합니다 기기가 다시 범위 안에 들어오면 Core Bluetooth가 다시 연결합니다
다음은 몇가지 제한사항입니다 이 제한사항들은 Apple Watch 최적의 배터리 수명을 위해 중요한 사항들입니다
장치가 블루투스 범위의 가장자리에 있는 경우 백그라운드 BLE 연결 중에 반복적으로 연결이 끊어지며 재접속 범위가 줄어들게 됩니다 즉, Apple Watch와 가까운 기기만 다시 연결됩니다
이러한 제한은 최근 24시간을 참고하며 사용자가 앱과 상호 작용할 때마다 재설정됩니다
또 다른 제한은 적절한 알림을 위한 백그라운드 런타임 시도의 수에 관한 것입니다
사용자에게 중요한 일이 발생할 때 변경될 특성만 모니터링 합니다 기기에서 주기적으로 데이터를 수집해야 하는 경우에는 백그라운드 앱 새로 고침으로 수행해야 합니다
앱이 제한을 초과하려고 하면 LeGattNearBackground NotificationLimit 알림을 보내죠 앱에서 해당 오류를 모니터링해서 사용자가 watchOS 앱과 상호작용하지 않는다는 것을 아는 것이 좋습니다
이 알림이 중요하다면 네트워크 요청이나 블루투스 주변 장치의 UI 변경등과 같이 다른 방법으로 사용자와 소통해야 하는 적절한 때 일 수 있습니다
한도 초과 후에는 LeGattExceededBackground NotificationLimit 알림을 보내죠
이 이후부터 앱은 더 이상 백그라운드 런타임을 받지 않고 백그라운드 연결이 없고 백그라운드 앱 새로고침만 수행하는 watchOS 8 동작으로 되돌아갑니다
GATT 알림 업데이트의 에러 필드에서 이 두 가지 알림을 받을 수 있습니다 백그라운드 BLE 연결의 경우 한계에 도달했을 때를 알기 위해 카운트다운 대신 오류를 사용하는 것이 좋습니다
watchOS 9의 경우 백그라운드 런타임 제한이 5로 설정되며 이러한 제한은 모두 사용자가 앱과 상호 작용할 때마다 재설정되거나 앱과 사용자 상호 작용이 없으면 제한에 도달한 후 24시간이 지나면 재설정됩니다 이 제한은 블루투스 백그라운드 LE 연결에만 적용됨을 참고하세요 만일 컴플리케이션이 시계 페이스에서 활성 상태라면 이러한 제한과 별개로 백그라운드 앱 새로고침은 계속됩니다
각 이벤트를 처리하는 데 걸리는 시간은 매우 짧습니다 매우 복잡한 처리를 하기에는 시간이 충분하지 않을 수 있지만 사용자에게 중요한 일이 일어나고 있음을 경고하기엔 충분합니다 마지막으로 백그라운드에서 제때 알림을 수신하기 위해서는 Apple Watch Series 6 이상이 필요합니다 백그라운드에서 알림을 받는 것만 할 수 있는 것은 아닙니다 watchOS 9에선 앱이 백그라운드 때 주변 장치를 검색할 수 있습니다
블루투스 의료 기기와 제 때 알림을 받는 watchOS 앱이있다고 가정해 보겠습니다 전력을 절약하기 위해 주변 장치는 심각한 상태를 감지하기 전까지 알리지 않습니다
따라서 기기와 Apple Watch 간엔 아직 연결이 없습니다 이 때 watchOS 앱은 의료 기기의 고유한 서비스 UUID를 검색합니다
이제 의료 기기가 심각한 것을 감지하면 알림을 시작합니다 Apple Watch는 이 주변기기를 찾아 백그라운드에서 앱을 실행합니다
그리고 앱은 감지된 상태를 사용자에게 알리게 됩니다
작동 방식은 다음과 같습니다 Watch 앱은 주변기기 검색을 시작하고 Core Bluetooth는 백그라운드에서 계속 탐색합니다
주변기기의 알림이 감지되면 앱이 백그라운드 런타임을 갖고 연결을 시작할 수 있습니다
이를 위해 코드를 살펴보겠습니다 API는 watchOS 8에서 변경되지 않았지만 이제 앱이 백그라운드에 있는 경우에도 탐색이 적용됩니다
'scanForPeripherals'를 찾으려는 장치의 서비스 UUID로 호출합니다 앱이 실행중인 동안 이 작업을 수행할 수 있으며 백그라운드에 있는 동안에도 계속됩니다 'allowDuplicatesKey' 옵션의 경우 앱이 실행중일 때만 사용할 수 있습니다 이제 몇 가지 제한 사항에 대해 이야기해 보겠습니다
앱이 실행되는 사이에 앱에 백그라운드 런타임이 제공되는 횟수에는 제한이 있습니다 이 제한은 앞서 본 GATT 특성이 변경될 때 실행되는 백그라운드 런타임과 합산됩니다 백그라운드에서 주변 장치를 검색하는 것 역시 Apple Watch Series 6 이상이 필요합니다
요약하자면 이제 Apple Watch가 백그라운드에서 제한된 수의 블루투스 서비스 UUID를 스캔할 수 있습니다
이제 액세서리가 새로운 기능을 최대한 활용할 수 있도록 디자인하는 방법에 대해 이야기해 보겠습니다
블루투스 원격 액세서리를 디자인할 때 전력과 기능에 대해 절충해야 할 점이 있습니다
전력 소비가 문제인 경우 기기가 잠든 상태에서 알림이 발생해 관련된 정보만 알릴 수 있도록 이 도표에서 이곳에 위치하도록 해야합니다 여기서는 블루투스 탐색 지연을 늘리는 대신 더 많은 전력을 절약하는 절충안이 있습니다
이것이 의료기기에 대해 제공되는 절충안의 예시입니다
반면에 즉각적인 알림을 위한 짧은 대기 시간이 필요하지만 전력 소모가 중요한 문제가 아닐 때 백그라운드 LE 연결과 GATT 지시자를 이용해 알림을 보내는 방법을 고려해볼 수 있습니다 각 앱마다 두 개의 블루투스 연결 제한이 있습니다
이것은 온도계에 대해 적용되는 절충안의 예시입니다
사용자들이 제때 알림을 받는 것에 대한 최상의 경험을 위해 시간이 중요한 데이터와 그렇지 않은 데이터를 필터링할 수 있도록 주변 장치에 프로세싱과 인텔리전스를 추가해보세요
온도계 예시로 돌아가보면 모든 온도를 전송하는게 아니라 중요한 사건이 있거나 온도 변경 때에만 알림을 보내는 방식입니다 이 접근 방식의 이점은 주기적인 데이터에서 시간이 중요한 이벤트를 구분해서 주변기기와 Apple Watch 사용자 모두 전력을 절약해 더 나은 경험을 제공하는 것입니다
장치 연결이 끊어지면 다시 연결하도록 알리기를 권장합니다 알림 간격은 재연결에 필요한 시간이 얼마나 걸리는지 배터리 수명은 어떤지와 같은 블루투스 주변기기의 필요 사항에 따라 다릅니다 액세서리 지침에서는 사용할 수 있는 몇 가지 값을 제공합니다 예를 들어 기기의 배터리가 제한된 경우 1022.5ms 값을 사용할 수 있습니다
또 다른 예시로 20ms의 속도로 알리는 경우 이상적인 조건이라면 1초 내에 감지할 수 있어야 합니다
중요한 사건이 있을 때만 이 높은 알림 간격을 사용할 수 있도록 설계할 수 있습니다
이제 연결 간격에 대해 이야기해 보겠습니다 기기가 백그라운드에서 연결을 유지하는 상태를 선택하는 경우 최소 150ms의 긴 연결 간격을 사용하는 것이 좋습니다 이렇게 하면 주변 장치의 배터리를 절약하며 Apple Watch에서 최고의 사용자 경험을 제공할 수 있습니다
Apple Watch엔 Connection Sub-rating이 포함된 Bluetooth 5.3이 제공됩니다 블루투스 주변 장치가 유휴 상태인 동안 접속 간격을 증가시킬 수 있고 더 짧은 대기 시간이 필요할 때 연결 간격을 더 짧게 할 수 있습니다
다음은 플랫폼 간의 차이점을 보여주는 표입니다 다음은 Bluetooth Low Energy에 대해 현재 지원되는 구성입니다 작년에 우리는 새로운 백그라운드 실행 모드로 watchOS용 백그라운드 앱 새로고침을 도입했습니다 올해는 Apple Watch Series 6 이상에 대해 오늘 설명한 대로 빠른 알림으로 백그라운드 실행을 개선했습니다
시청해주셔서 감사합니다!
-
-
3:41 - Listen for alerts
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { peripheral.setNotifyValue(true, for: characteristic) } func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let newData = characteristic.value { // Post a local notification. } }
-
9:15 - Discover peripherals
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { central.scanForPeripherals(withServices: [myCustomUUID]) }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.