Skip to content

Commit a72226e

Browse files
committed
test
1 parent ecb0d1d commit a72226e

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

src/lib/basic/timer.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,28 @@ export const rAF = () =>
99
new Promise(resolve => {
1010
requestAnimationFrame(resolve)
1111
})
12+
13+
/**
14+
* 条件が満たされるまでポーリングで待機する関数
15+
* @param condition 条件を判定する関数。trueを返したら待機終了
16+
* @param options.interval ポーリング間隔(ミリ秒)、デフォルト: 10ms
17+
* @param options.timeout 最大待機時間(ミリ秒)、デフォルト: 500ms
18+
* @returns 条件が満たされた場合true、タイムアウトした場合false
19+
*/
20+
export const waitUntil = async (
21+
condition: () => boolean,
22+
options?: { interval?: number; timeout?: number }
23+
): Promise<boolean> => {
24+
const interval = options?.interval ?? 10
25+
const timeout = options?.timeout ?? 500
26+
const startTime = Date.now()
27+
28+
while (!condition()) {
29+
if (Date.now() - startTime >= timeout) {
30+
return false
31+
}
32+
await wait(interval)
33+
}
34+
35+
return true
36+
}

src/lib/notification/notification.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from 'firebase/messaging'
77

88
import apis from '/@/lib/apis'
9-
import { wait } from '/@/lib/basic/timer'
9+
import { wait, waitUntil } from '/@/lib/basic/timer'
1010
import { isIOSApp, isPWA, isWebKit } from '/@/lib/dom/browser'
1111
import router from '/@/router'
1212
import { useToastStore } from '/@/store/ui/toast'
@@ -90,12 +90,37 @@ export const connectFirebase = async (onCanUpdate: OnCanUpdate) => {
9090
})()
9191

9292
if (permission === 'granted') {
93+
// iOS PWA の場合、許可状態がService Workerコンテキストに反映されるまで待つ
94+
// https://stackoverflow.com/questions/76590928/pwa-on-ios-notification-permission-return-default-whatever-we-chose
95+
if (isWebKit() && isPWA()) {
96+
const success = await waitUntil(
97+
() => Notification.permission === 'granted',
98+
{ interval: 10, timeout: 500 }
99+
)
100+
if (!success) {
101+
// eslint-disable-next-line no-console
102+
console.warn(
103+
'[Notification] iOS PWA: permission state did not update within timeout'
104+
)
105+
}
106+
}
93107
notify({ title: `ようこそ${appName}へ!!` }, true)
94108
} else {
95109
// eslint-disable-next-line no-console
96110
console.warn(`[Notification] permission ${permission}`)
97111
}
98112
}
113+
114+
// iOS PWAの場合、Service Worker登録前に許可状態を最終確認
115+
// Service Workerコンテキストは作成時の許可状態を保持するため、
116+
// 'granted' 状態で作成されることを保証する
117+
if (isWebKit() && isPWA() && Notification.permission !== 'granted') {
118+
// eslint-disable-next-line no-console
119+
console.warn(
120+
`[Notification] iOS PWA: permission is ${Notification.permission}, skipping service worker registration`
121+
)
122+
return
123+
}
99124
} else {
100125
// eslint-disable-next-line no-console
101126
console.warn(`[Notification] Notification does not exists`)

0 commit comments

Comments
 (0)