🌟

プッシュ通知で畜産農家さんの安眠を守る! iOS Critical Alertを実装しました

2021/12/23に公開

iOS/iPadOS端末がマナーモード中でも例外的に通知音を再生できる、Critical Alert(重大なお知らせ)。謎の多いこの機能を実装する機会がありましたので、手順をご紹介します。

Critical Alertとはなにか?

Critical Alert(重大なお知らせ)はマナーモードにしたiPhone/iPadで、特定のアプリの通知だけ通知音を再生できるiOS/iPadOSの機能です。

https://developer.apple.com/documentation/usernotifications/unauthorizationoptions/unauthorizationoptioncriticalalert?language=objc

多くのアプリケーションで使われる機能ではないので、存在を知らなかった方もいるかもしれません。有名どころでは『Yahoo! 防災速報』『特務機関NERV防災』などがこの機能に対応しています。

https://emg.yahoo.co.jp/
https://nerv.app/

マナーモード中でも通知音が鳴り、音量も指定できる

Critical Alertはプッシュ通知の一種ですが、ユーザーの許可を得た状態ならたとえマナーモードやお休みモードを設定していても通知音がなります。

また、この通知については送信側が音量を指定することができます。

専用のパーミッション画面が表示される

Critical Alertを利用する場合、通常の通知のパーミッションとは異なる特別なパーミッションが必要になります。
ユーザーに許可を求めるおなじみの画面も、こんな感じで若干ものものしいデザインになっています。

牛の監視システム「U-motion」へのCritical Alertの導入

私たちが開発しているU-motionは、センサーをつけた牛が転倒して起き上がれなくなった場合に通知を送信する「起立困難アラート」を提供しています。転倒を検知することで、迅速に該当の牛のもとに駆けつけて牛を起こし、死亡事故などを防ぐことができるようになります。また、同じアラート機能で分娩の兆候を通知する「分娩兆候アラート」も提供しています。

これらのアラートはユーザーである農家さんが就寝中に特に威力を発揮しますが、通常のプッシュ通知ではマナーモード中に通知音が鳴らないため農家さんが目を覚ますことが難しいという課題がありました。かといってマナーモードをOFFにすれば、今度は寝ている間に様々な通知音が鳴ることになり、落ち着いて眠れなくなってしまいます。

そこで思いついたのがCritical Alertです。『特務機関NERV防災』アプリなどで存在は知っていたのですが、この機能を利用するにはまずAppleへの申請が必要で審査もあります。自分達のアプリケーションで利用できるとは思っていませんでした。

しかしこの機能をサポートできれば牛の命を守れるだけでなく畜産農家さんがゆっくり眠ることもサポートできます。
審査に出してみようということになりました。

https://youtu.be/6Bw1wXX0i3s

Appleへの申請と審査

申請はウェブ・フォーム経由で、審査を経て許可が降りた際はメールでお知らせがくるというちょっと変わった仕組みになっています。

申請フォームには通知の送信頻度やアプリケーションがCritical Alertを必要とする理由などを記入します。
ちなみにやりとりは全て英語です。
海外の掲示板などで「申請を出して数ヶ月待ったけど返事がない」という書き込みも目にしていたので恐らく時間がかかるだろうと思っていたのですが、申請から1ヶ月もしない間にメールが届いてあっさりと許可がおりました。
チーム内で意見を結集して、このアラートが農家さんにとっていかに重要か、日本の畜産事情も交えて説明したのが良かったのでしょうか。

まずは第一関門突破、いよいよ実装です。

Apple Developer PortalでCapabilityにCritical Alertを追加

まずはブラウザを開き、DeveloperポータルでIdentifiersの中から対象のアプリケーションを選択します。
Additional Capabilities というタブに Critical Alert が追加されています。特別な機能を使えているという密かな喜びがあります。
Enabledをチェック✅します。

Entitlementの入力

Critical Alertを利用するアプリケーションのプロジェクトをXcodeで開き、Entitlementファイルに com.apple.developer.usernotifications.critical-alerts というキーでエントリを追加し、valueに true をセットします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.usernotifications.critical-alerts</key>
	<true/>
</dict>
</plist>

パーミッション: UNAuthorizationOptionCriticalAlert

プッシュ通知の送信のためにユーザーのパーミッションを得る必要がありますが、Critical Alertを送信する場合はさらに UNAuthorizationOptionCriticalAlert をoptionsに含めます(Obj-Cの場合)。

UNAuthorizationOptions options = UNAuthorizationOptionNone;

options |= UNAuthorizationOptionAlert;
options |= UNAuthorizationOptionBadge;
options |= UNAuthorizationOptionSound;
options |= UNAuthorizationOptionCriticalAlert; // ← こちらを追加します

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError *_Nullable error) {
    if (error) {
      reject(@"request_error", @"requestAuthorizationWithOptions failed", error);
  } else {
      NSLog(@"requestPermission success");
      resolve(granted ? (id) @"1" : (id) @"0");
  }
}];

requestAuthorizationWithOptions を呼び出すと、冒頭のスクリーンショットにあったCritical Alert専用のパーミッション・ダイアログが表示されます。

FirebaseでCritical Alertを送信

端末側でCritical Alertの受信の準備ができたら、サーバから実際にアラートを送信します。

U-motinoはプッシュ通知の送信にはFirebase Cloud Messaging(FCM)を使用しているのでFCMをベースに解説します。
FCMはiOSのCritical Alertに対応していて、ペイロードに必要なプロパティーを含めるだけで通知を送信できます。

aps: {
    sound: { 
        critical: 1,
        name: 'default',
        volume: 0.5
    }
}

この図のようにペイロードの sound をObjectにしてプロパティー critical: true  をセットします。
name は再生する音源の名前、 volume は再生する音量です。
1.0をセットするとだいぶ大きめの音が鳴ります。

Critical Alertが届く

おやすみモードにセットした端末に向けて、テスト通知を送信します。
通知音が鳴り、重大な通知のバナーが表示されました。

まとめ

iOSのCritical Alertを実装してみました。フォームによる利用申請など実装外の作業があり、またAppleが申請を許可するかどうかなど不明な点も多いのでまずは審査をクリアするところから始めて見るのが良いと思います。

マナーモードに設定した端末で通知音が鳴る様子はなかなか特別なものがあります。実装するチャンスがなかなか無い珍しい機能ですが、参考になれば嬉しい限りです。

Discussion