PushizoDocs
Kanallar

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" }
  ]
}
```text

```html
<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" />
```text

`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`:

```js
const apiUrl = new URL(self.location.href).searchParams.get('apiUrl') || 'https://api.example.com';
importScripts(`${apiUrl.replace(/\/$/, '')}/sdk-web/PushizoSDKWorker.js`);
```text

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

```ts
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();
```text

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ı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

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