iOS — APNs kurulumu
Open Notification Apple ile doğrudan, HTTP/2 üzerinden, token tabanlı (.p8) kimlik doğrulama anahtarıyla konuşur. Tek anahtar ekibinizdeki her uygulamaya ve hem sandbox hem production ortamına hizmet eder — her yıl yenilenecek bir şey yok.
A Bölümü — Apple Developer portalında anahtarı oluşturma
1 developer.apple.com/account'a Admin ya da Account Holder rolündeki bir hesapla girin (App Manager'lar anahtar oluşturamaz).
2 Sol kenar çubuğunda Certificates, Identifiers & Profiles → Keys'i açın.
3 Keys başlığının yanındaki + düğmesine tıklayın.
4 Sonra tanıyacağınız bir ad verin (örn. Open Notification APNs) ve Apple Push Notifications service (APNs) kutusunu işaretleyin.
2024'ten beri APNs kutusunun yanında Sandbox & Production ya da yalnızca Sandbox sunan bir Configure düğmesi var. Sandbox & Production'ı seçin.
5 Continue, gözden geçirin, sonra Register.
6 Download'a tıklayın. AuthKey_XXXXXXXXXX.p8 iner. Apple tam olarak bir kez indirmenize izin verir. Güvenli bir yerde saklayın (parola yöneticisinin dosya eki ideal). Kaybederseniz anahtarı iptal edip yenisini oluşturun.
7 Artık gereken üç tanımlayıcıyı not edin:
| Tanımlayıcı | Nerede | Görünüm |
|---|---|---|
| Key ID | Keys altında anahtarın sayfasında ve dosya adında. | 7K3M9PQ2XB (10 karakter) |
| Team ID | Portalın sağ üstünde, adınızın altında; ayrıca Membership details. | A1B2C3D4E5 (10 karakter) |
| Bundle ID | Xcode → hedef → General → Bundle Identifier; ya da portalda Identifiers. | com.acme.shop |
B Bölümü — Uygulamada push'u açma
8 App ID'nin Push Notifications yetkisi olduğundan emin olun: Certificates, Identifiers & Profiles → Identifiers → uygulamanız → Push Notifications işaretli → Save. (Otomatik imzalamayla yetkiyi eklediğinizde Xcode bunu sizin için yapar.)
9 Xcode'da uygulama hedefini seçin → Signing & Capabilities → + Capability ve ekleyin:
- Push Notifications
- Background Modes → Remote notifications işaretli
10 Bir Notification Service Extension hedefi ekleyin (File → New → Target… → Notification Service Extension). Onsuz iOS'ta delivered olayı, görsel ve aksiyon butonu yoktur. SDK hazır bir NotificationService.swift ile gelir; bağlantısı iOS SDK sayfasında.
C Bölümü — Anahtarı Open Notification'a yükleme
Panelden — Kimlik bilgileri › APNs:

…ya da komut satırından:
bun run app:create -- --name "Acme" --slug acme \
--apns-p8 ./AuthKey_7K3M9PQ2XB.p8 \
--apns-key-id 7K3M9PQ2XB \
--apns-team-id A1B2C3D4E5 \
--apns-bundle-id com.acme.shop \
--apns-production
.p8 gelir gelmez ENCRYPTION_KEY ile mühürlenir ve hiçbir API tarafından döndürülmez.
Sandbox mı production mı
| Build | Host | Ayar |
|---|---|---|
| Xcode debug build, development profiliyle imzalı TestFlight internal build'ler | api.sandbox.push.apple.com | Production APNs kapalı |
| App Store, TestFlight (App Store dağıtımı), Ad Hoc | api.push.apple.com | Production APNs açık |
Bir ortamın token'ı diğerinde BadDeviceToken ile reddedilir. İkisi aynı anda gerekiyorsa Open Notification'da aynı .p8 ve farklı ayarlarla iki uygulama (acme ve acme-dev) oluşturun.
D Bölümü — Doğrulama
11 Kimlik bilgileri sayfasında Bağlantıyı test et'e basın. API anahtarınızla JWT imzalar ve kasıtlı olarak geçersiz bir token'a gönderir:
| Sonuç | Anlamı |
|---|---|
✅ BadDeviceToken | Apple sizi doğruladı ve sahte token'ı reddetti. Anahtar, Key ID, Team ID ve Bundle ID doğru. |
❌ InvalidProviderToken | Key ID / Team ID / .p8 birbiriyle uyuşmuyor. |
❌ TopicDisallowed / 403 | Anahtar geçerli ama bu Bundle ID'ye gönderemez — App ID'nin push yetkisini kontrol edin ya da anahtar APNs olmadan oluşturulmuş. |
❌ MissingProviderToken | .p8 dosyası boş ya da PEM değil. |
Sunucu ne gönderir
Referans olarak cihazın aldığı yük:
{
"aps": {
"alert": { "title": "Yeni eşleşme", "body": "3 kişi seni beğendi" },
"sound": "default",
"badge": 1,
"mutable-content": 1,
"thread-id": "matches",
"interruption-level": "time-sensitive",
"category": "on_66f1a…"
},
"on": {
"m": "<imzalı msgId>",
"c": "<campaignId>",
"url": "acme://matches",
"img": "https://cdn.example.com/x.jpg",
"d": { "screen": "matches" },
"a": [{ "id": "view", "title": "Gör" }]
}
}
mutable-content: 1 her zaman ayarlıdır — extension'ı uyandıran budur. interruption-level, priority: "high" için time-sensitive, aksi halde active; apns-priority 10 / 5 ile uyumludur. Sessiz bildirimde sound anahtarı hiç yoktur (presentation.sound = "none" bunu üretir). apns-collapse-id ve apns-expiration collapseId ve ttl'den gelir.
Sunucuda hata yönetimi
| APNs nedeni | Worker |
|---|---|
BadDeviceToken, Unregistered, DeviceTokenNotForTopic | Abonelik geçersiz kılınır. Asla tekrar denenmez. |
ExpiredProviderToken | JWT yenilenir, tekrar denenir. |
TooManyRequests, ServiceUnavailable | Üstel backoff ile en çok 3 deneme. |
TooManyProviderTokenUpdates | Yalnızca JWT 20 dakikadan sık yenilenseydi olurdu; worker uygulama başına önbellekler. |