iOS Safari (16.4+) web push ve PWA
iOS 16.4 ve sonrasında Safari, ana ekrana eklenmiş web uygulamalarına (PWA) standart Web Push ile bildirim gönderebilir. Pushizo Web SDK'sı bu akışı ek kod olmadan destekler; farklı olan, kullanıcının siteyi önce ana…
iOS 16.4 ve sonrasında Safari, ana ekrana eklenmiş web uygulamalarına (PWA) standart Web Push ile bildirim gönderebilir. Pushizo Web SDK'sı bu akışı ek kod olmadan destekler; farklı olan, kullanıcının siteyi önce ana ekrana eklemesi ve iznin yalnızca bir kullanıcı hareketiyle istenebilmesidir. Bu rehber gereksinimleri, Pushizo.Notifications.requestPermission akışını ve PWA sınırlamalarını anlatır.
1. Gereksinimler
| Gereksinim | Açıklama |
|---|---|
| iOS / iPadOS 16.4+ | Daha eski sürümlerde PushManager yoktur; SDK Pushizo.Notifications.permission değerini 'unsupported' döndürür. macOS Safari 16+ için ana ekrana ekleme gerekmez. |
| HTTPS | localhost dışında zorunlu. |
| Web app manifest | display: standalone (ya da fullscreen, minimal-ui) ile bağlı bir manifest.webmanifest. display: browser olan siteler bildirim alamaz. |
| Ana ekrana ekleme | Kullanıcı Paylaş → Ana Ekrana Ekle yapmalıdır; Safari sekmesinde açık siteye iOS'ta push verilmez. |
| Kullanıcı hareketi | Notification.requestPermission() yalnızca dokunma/tıklama işleyicisi içinde çağrılabilir; otomatik istem (autoPrompt) iOS'ta sessizce reddedilir. |
| Service worker | Site kökünde PushizoSDKWorker.js (SDK varsayılanı /PushizoSDKWorker.js). |
| Web Push kanalı | Dashboard → Kanallar → Web Push etkin (VAPID anahtarı GET /sdk/v1/apps/{app_id}/config içinde web.vapid_public_key olarak iner). |
2. Manifest
{
"name": "Mağaza",
"short_name": "Mağaza",
"start_url": "/?source=pwa",
"scope": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2563eb",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}<link rel="manifest" href="/manifest.webmanifest" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Mağaza" />
<link rel="apple-touch-icon" href="/icons/icon-180.png" />start_url ve scope service worker kapsamıyla (/) aynı origin'de olmalıdır. Bildirim ikonu olarak Safari manifest ikonunu kullanır; chrome_web_icon alanı iOS'ta yok sayılır.
3. Service worker
Site kökünde PushizoSDKWorker.js:
const apiUrl = new URL(self.location.href).searchParams.get('apiUrl') || 'https://api.example.com';
importScripts(`${apiUrl.replace(/\/$/, '')}/sdk-web/PushizoSDKWorker.js`);Mevcut bir PWA service worker'ınız varsa (ör. önbellekleme için) aynı importScripts satırını ona ekleyip init seçeneklerinde serviceWorkerPath ile dosyanın yolunu verin; iOS'ta tek bir kayıt kapsamı (/) kullanmak en güvenlisidir.
4. Akış: ana ekrana ekleme → izin → abonelik
import Pushizo from '@pushizo/web';
await Pushizo.init({
appId: 'app_…',
apiUrl: 'https://api.example.com',
autoPrompt: false, // iOS'ta otomatik istem çalışmaz; düğmeyle isteyin
welcomeNotification: { disable: true }, // ilk abonelikte yerel karşılama bildirimi (iOS'ta da gösterilir; isteğe bağlı)
});
const ua = navigator.userAgent;
const isIOS = /iPhone|iPad|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
const isStandalone =
window.matchMedia('(display-mode: standalone)').matches || (navigator as { standalone?: boolean }).standalone === true;
function renderPushState() {
const permission = Pushizo.Notifications.permission; // 'default' | 'granted' | 'denied' | 'unsupported'
if (permission === 'unsupported') {
// iOS 16.4+ ancak ana ekrana eklenmemiş: PushManager yok → yönlendirme göster
if (isIOS && !isStandalone) showAddToHomeScreenHint();
else showUnsupported();
return;
}
if (permission === 'denied') {
showSettingsHint(); // iOS: Ayarlar → Bildirimler → <uygulama adı>
return;
}
if (Pushizo.User.pushSubscription.optedIn) showSubscribed();
else showSubscribeButton();
}
document.getElementById('subscribe')!.addEventListener('click', async () => {
// Kullanıcı hareketi içinde: izin + abonelik (POST /sdk/v1/apps/{appId}/subscriptions)
const granted = await Pushizo.Notifications.requestPermission();
if (granted) await Pushizo.login(currentUserId); // kimlik biliniyorsa cihazı kullanıcıya bağla
renderPushState();
});
Pushizo.User.pushSubscription.addObserver(() => renderPushState());
renderPushState();Notlar:
requestPermission()izin verildiğinde service worker üzerindenPushManager.subscribeçağırır ve aboneliği Pushizo'ya kaydeder;true/falsedöner. Abonelik kimliğiPushizo.User.pushSubscription.id.Notifications.requestPermission()doğrudan çağrısı istem geri çekilme takviminden etkilenmez;Slidedown.promptPush()ise 3/7/30 gün takvimine uyar. iOS'ta slidedown'ın "Abone ol" düğmesi de kullanıcı hareketi sayılır.- Ana ekrana ekleme ipucu için
display-mode: standaloneortam sorgusu (isStandalone) venavigator.standalonebirlikte kontrol edilir;beforeinstallpromptolayı Safari'de yoktur. - Kullanıcı PWA'yı ana ekrandan silerse Apple aboneliği sonlandırır; sonraki gönderimde sağlayıcı
410döner ve abonelik otomatikinvalidolur (Mesaj İzleme'de görünür). allowLocalhostAsSecureOriginyalnızca masaüstü geliştirme içindir; iOS cihazdan test için HTTPS (ör.ngrok/cloudflaredtüneli ya da geçerli sertifikalı LAN alan adı) gerekir.
5. Bildirim içeriği ve tıklama
- Safari başlık, gövde ve
urlkullanır;chrome_web_icon,chrome_web_badge,chrome_web_image,web_buttonsverequire_interactioniOS'ta uygulanmaz (yok sayılır, hata üretmez). Görsel ekleyen bildirimler iOS'ta yalnızca metin gösterir. - Tıklama: service worker
urlalanındaki adresi PWA penceresinde açar (notificationClickHandlerMatch/notificationClickHandlerActiondavranışı aynıdır);openedkaydı vedelivery.openedwebhook'u üretilir. Hedef URL manifestscopedışındaysa iOS, adresi Safari'de açar. - Teslimat onayı (
received) service workerpusholayında raporlanır; PWA kapalıyken de çalışır. - Rozet: iOS 16.4+
navigator.setAppBadgedestekler; Pushizo SDK'sı rozet yazmaz, istersenizInbox.unreadCount()değerininavigator.setAppBadge(n)ile gösterin.
6. PWA sınırlamaları
| Sınırlama | Etki / öneri |
|---|---|
| Push yalnızca ana ekrana eklenmiş uygulamada | Safari sekmesinde permission === 'unsupported'; kullanıcıya "Ana Ekrana Ekle" adımlarını gösterin. |
| İzin yalnızca kullanıcı hareketiyle | autoPrompt: true ve otomatik slidedown kabulü iOS'ta izin vermez; düğme kullanın. |
| Sessiz push yok | content_available (veri) mesajları iOS web'de teslim edilmez; görünür bildirim gönderin. |
| Sabit ikon | Manifest ikonu; mesaj başına ikon/rozet/görsel yok. |
| Aksiyon düğmeleri yok | web_buttons yok sayılır; tıklama bildirimin url'sini açar. |
| Her PWA ayrı izin | Aynı siteyi iki kez ekleyen kullanıcı iki ayrı abonelik alır; login ile aynı kullanıcıda birleşir. |
| Arka plan senkronu yok | Çevrimdışı kuyruk (localStorage) bir sonraki açılışta boşaltılır. |
| Depolama temizliği | Safari, 7 gün kullanılmayan site verisini silebilir; hs:<appId> yerel durumu silinirse SDK açılışta aboneliği sunucudan eşler (autoResubscribe). |
7. Doğrulama
- iOS cihazda HTTPS adresi Safari'de açın → Paylaş → Ana Ekrana Ekle → uygulamayı ana ekrandan başlatın.
- "Bildirimlere izin ver" düğmesine dokunun → sistem istemi → izin verin. Dashboard → Abonelikler'de
web_pushkaydı (device.os = iOS) görünür. - Kaydı Test cihazı yapıp Mesajlar → Test push gönder. Bildirim kilit ekranında görünür; dokununca PWA açılır ve Mesaj İzleme'de
openedgörünür. - Sorun giderme:
permission: unsupported→ ana ekrana eklenmemiş ya da iOS < 16.4; abonelik oluşmuyor → Web Push kanalı kapalı (web.vapid_public_keyboş) ya da service worker 404; bildirim gelmiyor → Mesaj İzleme'deki sağlayıcı yanıtına bakın (410abonelik iptal,401/403VAPID anahtarı değişmiş).
Firebase Cloud Messaging'den (FCM) Pushizo'ya göç
Bildirimleri doğrudan Firebase Cloud Messaging (FCM HTTP v1 API, Firebase Admin SDK ya da Firebase konsolu) ile gönderiyorsanız bu rehber Pushizo'ya geçişi anlatır. Pushizo Android'de FCM'i taşıma katmanı olarak…
iOS critical alert, interruption level ve ses
Bu rehber Pushizo'nun iOS bildirimlerinde desteklediği aps alanlarını, ios_interruption_level (time-sensitive / critical) kullanımını ve ses/hacim davranışını açıklar. Critical alert, Apple'ın yalnızca başvuruyla…