Pushizo Docs
Rehberler

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

GereksinimAçı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.
HTTPSlocalhost dışında zorunlu.
Web app manifestdisplay: standalone (ya da fullscreen, minimal-ui) ile bağlı bir manifest.webmanifest. display: browser olan siteler bildirim alamaz.
Ana ekrana eklemeKullanıcı Paylaş → Ana Ekrana Ekle yapmalıdır; Safari sekmesinde açık siteye iOS'ta push verilmez.
Kullanıcı hareketiNotification.requestPermission() yalnızca dokunma/tıklama işleyicisi içinde çağrılabilir; otomatik istem (autoPrompt) iOS'ta sessizce reddedilir.
Service workerSite 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 üzerinden PushManager.subscribe çağırır ve aboneliği Pushizo'ya kaydeder; true/false döner. Abonelik kimliği Pushizo.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: standalone ortam sorgusu (isStandalone) ve navigator.standalone birlikte kontrol edilir; beforeinstallprompt olayı Safari'de yoktur.
  • Kullanıcı PWA'yı ana ekrandan silerse Apple aboneliği sonlandırır; sonraki gönderimde sağlayıcı 410 döner ve abonelik otomatik invalid olur (Mesaj İzleme'de görünür).
  • allowLocalhostAsSecureOrigin yalnızca masaüstü geliştirme içindir; iOS cihazdan test için HTTPS (ör. ngrok/cloudflared tü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 url kullanır; chrome_web_icon, chrome_web_badge, chrome_web_image, web_buttons ve require_interaction iOS'ta uygulanmaz (yok sayılır, hata üretmez). Görsel ekleyen bildirimler iOS'ta yalnızca metin gösterir.
  • Tıklama: service worker url alanındaki adresi PWA penceresinde açar (notificationClickHandlerMatch/notificationClickHandlerAction davranışı aynıdır); opened kaydı ve delivery.opened webhook'u üretilir. Hedef URL manifest scope dışındaysa iOS, adresi Safari'de açar.
  • Teslimat onayı (received) service worker push olayında raporlanır; PWA kapalıyken de çalışır.
  • Rozet: iOS 16.4+ navigator.setAppBadge destekler; Pushizo SDK'sı rozet yazmaz, isterseniz Inbox.unreadCount() değerini navigator.setAppBadge(n) ile gösterin.

6. PWA sınırlamaları

SınırlamaEtki / öneri
Push yalnızca ana ekrana eklenmiş uygulamadaSafari sekmesinde permission === 'unsupported'; kullanıcıya "Ana Ekrana Ekle" adımlarını gösterin.
İzin yalnızca kullanıcı hareketiyleautoPrompt: true ve otomatik slidedown kabulü iOS'ta izin vermez; düğme kullanın.
Sessiz push yokcontent_available (veri) mesajları iOS web'de teslim edilmez; görünür bildirim gönderin.
Sabit ikonManifest ikonu; mesaj başına ikon/rozet/görsel yok.
Aksiyon düğmeleri yokweb_buttons yok sayılır; tıklama bildirimin url'sini açar.
Her PWA ayrı izinAynı 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ğiSafari, 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

  1. iOS cihazda HTTPS adresi Safari'de açın → Paylaş → Ana Ekrana Ekle → uygulamayı ana ekrandan başlatın.
  2. "Bildirimlere izin ver" düğmesine dokunun → sistem istemi → izin verin. Dashboard → Abonelikler'de web_push kaydı (device.os = iOS) görünür.
  3. 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 opened görünür.
  4. Sorun giderme: permission: unsupported → ana ekrana eklenmemiş ya da iOS < 16.4; abonelik oluşmuyor → Web Push kanalı kapalı (web.vapid_public_key boş) ya da service worker 404; bildirim gelmiyor → Mesaj İzleme'deki sağlayıcı yanıtına bakın (410 abonelik iptal, 401/403 VAPID anahtarı değişmiş).

Bu sayfada