Help us understand the problem. What is going on with this article?

iOSのExposureNotificationのAPIをサンプルアプリとドキュメントから見てみる

ExposureNotification概要

ExposureNotificationはCOVID-19への潜在的な曝露を人々に通知します。
ExposureNotificationの機能を実現するにはExposure Notification Serverの実装が必須です。

おことわり

実機ビルドするには Exposure Notification Entitlement Requestで申請する必要があり、ハードルが高いので、
あくまで、公式ドキュメントとサンプルアプリのシミュレータでの確認になっています。
大いに間違っている可能性があるので公式ドキュメントを正としてください。

公式ドキュメント

https://developer.apple.com/documentation/exposurenotification

サンプルアプリ

https://developer.apple.com/documentation/exposurenotification/building_an_app_to_notify_users_of_covid-19_exposure

ENManager

activate

func activate(completionHandler: @escaping ENErrorHandler)

ENManagerを使う前に最初に呼び出す。
これを行い、完了ハンドラが戻ってきたところでENManagerの機能が使えるようになる。

setExposureNotificationEnabled

func setExposureNotificationEnabled(_ enabled: Bool,completionHandler: @escaping ENErrorHandler)

曝露通知を有効/無効にするクラス。
自動的に通知許可をもらうダイアログも表示する。
許可が断られた場合、completionHandlerはENError.notAuthorizedを返す?
enabledをfalseにした場合、 Bluetoothのスキャンとアドバタイズを停止するが、取得していた診断データはそのまま残る。
残念ながらシミュレータで動作させてもDomain=NSOSStatusErrorDomain Code=-71148 のErrorになります。

detectExposures

func detectExposures(configuration: ENExposureConfiguration, 
    diagnosisKeyURLs: [URL], 
   completionHandler: @escaping ENDetectExposuresHandler) -> Progress

曝露を検出する。
diagnosisKeyURLsは、Exposure Notification ServerからダウンロードしたキーのローカルURLとする。
configurationに関しても、Exposure Notification Serverから取得するデータから生成することをサンプルアプリでは想定している。

このAPIはBluetooth経由で得ているデータをワンショット返すようで、サンプルアプリではBackgroundTasksフレームワークを用いて定期的に検出を行っている。

completionHandlerで返ってくる ENDetectExposuresHandler には ENExposureDetectionSummary が含まれていて、後述の getExposureInfo で使用する。

getExposureInfo

func getExposureInfo(summary: ENExposureDetectionSummary, 
     userExplanation: String, 
   completionHandler: @escaping ENGetExposureInfoHandler) -> Progress

前述の detectExposures から得た ENExposureDetectionSummary をパラメータにして曝露情報を取得する。
userExplanation はUIの一部としてユーザーに表示するために使われる。
コールバックとして ENExposureInfo が受け取れる。
サンプルアプリではこの情報を独自の構造にマッピングしてローカルに保存している。

getDiagnosisKeys

func getDiagnosisKeys(completionHandler: @escaping ENGetDiagnosisKeysHandler)

ENTemporaryExposureKey を取得する。
このメソッドを呼び出すたびに、ユーザーは承認を行う必要がある。
このキーはそのままExposure Notification Serverに送信する必要があり、サンプルアプリでは一旦JSONにデコードして送信する想定となっている。

getTestDiagnosisKeys

func getTestDiagnosisKeys(completionHandler: @escaping ENGetDiagnosisKeysHandler)

getDiagnosisKeys のテスト用API。
シミュレータで動作させてもDomain=NSOSStatusErrorDomain Code=-71148 のErrorになります。

invalidate

func invalidate()

ENManagerを無効にする。

ENStatus

曝露通知システムの有効状態を示すenum。
特筆したいのがbluetoothOffという種別であり、ENStatusにしかBluetooth使用を示すものがないので、ExposureNotificationのフレームワーク内で完全にBluetoothの処理は閉じていてBluetoothに対するコントロールは出来なさそう。

tvOS14(おまけ)

tvOS14にもExposureNotification.frameworkが有効なんですが、

  • ENAuthorizationStatus
  • ENStatus
  • ENError

と、限定的なAPIしか使えず、メインのENManagerが使えない模様。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした