PWAをiOSで試したときに手こずった話

結論

通知の許可を求めるには、ユーザからのアクションが必要だよ。ページアクセスのタイミングで勝手に許可を求めることはできないよ。

はじめに

この記事は、「なんかPWAってやつであたかもネイティブアプリのようにプッシュ通知を送信できるらしいけど、iOSでうまくいかないな~」と思っている稀有な方に向けたものです。

PWA導入システムの背景

  • 少し特殊な事情があり、使用ユーザはごくごく一部に限られていること

  • ユーザは、プッシュ通知を許可する前提で使用を始める、という同意書を書く(プッシュ通知はオプトアウト)

といった背景があり、ユーザがアクセスしたタイミングで、「通知の許可」を求めるダイアログを表示したいという事情がありました。

2つ目の前提は一般的には受け入れられない仕様だとは思うのですが、治験や臨床試験向けのシステムでは意外とこのような仕様があります。

何をしようとしたか

ページにアクセスしたタイミングで、Push通知を許可する以下の関数を実行してみました。

async function allowPush() {
    if ('Notification' in window) {
        let permission = Notification.permission;

        if (permission === 'denied') {
            alert('push denied...');
            return false;
        }
    }
   
    const appServerKey = 'xxxxxxxxxxxxxxx';
    const applicationServerKey = urlB64ToUint8Array(appServerKey);

    let subscription = undefined;
    try {
        subscription = await window.sw.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey
        });
    } catch (e) {
        alert('Push通知でエラーが発生しました。');
        return false;
    }


    // トークンの変換
    const key = subscription.getKey('p256dh');
    const token = subscription.getKey('auth');
    const request = {
        endpoint: subscription.endpoint,
        userPublicKey: btoa(String.fromCharCode.apply(null, new Uint8Array(key))),
        userAuthToken: btoa(String.fromCharCode.apply(null, new Uint8Array(token)))
    };

}

windowsPCのchromeで試したところ、望み通りアクセスしたタイミングで自動的に通知の許可を求めるダイアログが表示され、お!もしかしていける?と思いきや、iOSChromeiOSsafariで上手く動作せず・・・ 調べてみると、

パーミッションの要求 通知を表示するには、まずパーミッション(permission)を要求する必要があります。 ただちに通知を表示する代わりに、次のようにユーザーがボタンをクリックして要求したときにポップアップを表示することをお勧めします。

はい、すみませんでした・・・

ということで、ページにアクセスしたタイミングではなく、結局通知を許可するボタンを押してもらうことで対応しました、というお話。