/push-notifications
Implement, review, or debug push notifications in iOS/macOS apps — local notifications, remote (APNs) notifications, rich notifications, notification actions, silent pushes, and notification service/content extensions. Use when working with UNUserNotificationCenter, registering
$ npx -y skills add dpearson2699/swift-ios-skills --skill push-notifications --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/push-notifications
Context preview
The summary Claude sees to decide when to auto-load this skill.
Implement, review, or debug push notifications in iOS/macOS apps — local notifications, remote (APNs) notifications, rich notifications, notification actions, silent pushes, and notification service/content extensions. Use when working with UNUserNotificationCenter, registering
SKILL.md
push-notifications.SKILL.mdname: push-notifications
description: "Implement, review, or debug push notifications in iOS/macOS apps — local notifications, remote (APNs) notifications, rich notifications, notification actions, silent pushes, and notification service/content extensions. Use when working with UNUserNotificationCenter, registering for remote notifications, handling notification payloads, setting up notification categories and actions, creating rich notification content, or debugging notification delivery. Also use when working with alerts, badges, sounds, background pushes, or user notification permissions in Swift apps."
Push Notifications
Implement, review, and debug local and remote notifications on iOS/macOS using `UserNotifications` and APNs. Covers permission flow, token registration, payload structure, foreground handling, notification actions, grouping, and rich notifications. Targets iOS 26+ with Swift 6.3, backward-compatible to iOS 16 unless noted.
Keep adjacent domains separate: Live Activity `content-state` payloads belong in `activitykit`; PushKit/VoIP call pushes belong in `callkit`; App Clip ephemeral notification setup belongs in `app-clips`; long-running or scheduled background work after a silent push belongs in `background-processing`.
Contents
- [Correction Reviews](#correction-reviews)
- [Permission Flow](#permission-flow)
- [APNs Registration](#apns-registration)
- [Local Notifications](#local-notifications)
- [Remote Notification Payload](#remote-notification-payload)
- [Notification Handling](#notification-handling)
- [Notification Actions and Categories](#notification-actions-and-categories)
- [Notification Grouping](#notification-grouping)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Correction Reviews
When reviewing flawed notification proposals, explicitly name the violated contract. APNs token reviews must say token registration is independent from alert authorization, upload on every `didRegister` callback, avoid local-cache-as-truth logic, never assume token length, and treat Simulator registration failure as expected while noting `.apns` files or `simctl push` can simulate delivery. Background-push reviews must say `content-available` only, `apns-push-type: background`, `apns-priority: 5`, Remote notifications background mode, low priority, throttled, not guaranteed, not every few minutes, and bounded `didReceiveRemoteNotification` returning the correct `UIBackgroundFetchResult`. Rich-notification reviews must say service extensions require `mutable-content: 1` plus an alert payload, silent pushes do not trigger them, attachments are supported on-disk files that the system validates and stores, secrets use Keychain Sharing while App Groups are for shared files/UserDefaults, communication notifications require capability + `NSUserActivityTypes` + `INInteraction` donation + `content.updating(from:)`, and every service-extension path including attachment/download failures and `serviceExtensionTimeWillExpire()` must call the content handler exactly once with original, best-attempt, or updated content.
Permission Flow
Request notification authorization before scheduling or displaying user-visible alerts, sounds, or badges. The system prompt appears only once; subsequent calls return the stored decision. APNs token registration is separate: call `registerForRemoteNotifications()` when the app needs a device token, even if the user hasn't granted alert authorization.
import UserNotifications
@MainActor
func requestNotificationPermission() async -> Bool {
let center = UNUserNotificationCenter.current()
do {
let granted = try await center.requestAuthorization(
options: [.alert, .sound, .badge]
)
return granted
} catch {
print("Authorization request failed: \(error)")
return false
}
}Checking Current Status
Always check status before assuming permissions. The user can change settings at any time.
@MainActor
func checkNotificationStatus() async -> UNAuthorizationStatus {
let settings = await UNUserNotificationCenter.current().notificationSettings()
return settings.authorizationStatus
// .notDetermined, .denied, .authorized, .provisional, .ephemeral
}Provisional Notifications
Provisional notifications deliver quietly to the notification center without interrupting the user. The user can then choose to keep or turn them off. Use for onboarding flows where you want to demonstrate value before asking for full permission.
// Delivers silently -- no permission prompt shown to the user
try await center.requestAuthorization(options: [.alert, .sound, .badge, .provisional])
Critical Alerts
Critical alerts bypass Do Not Disturb and the mute switch. Requires a special entitlement from Apple (request via developer portal). Use only for health, safety, or security scenarios.
// Requires com.apple.developer.usernotifications.critical-alerts entitlement
try await center.requestAuthorization(
options: [.alert, .sound, .badge, .criticalAlert]
)Handling Denied Permissions
When the user has denied notifications, guide them to Settings with `UIApplication.openSettingsURLString`. Do not repeatedly prompt or nag.
APNs Registration
Use `UIApplicationDelegateAdaptor` to receive the device token in a SwiftUI app. The AppDelegate callbacks are the only way to receive APNs tokens.
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
UNUserNotificationCenter.current().delegate =Read more
name: push-notifications description: "Implement, review, or debug push notifications in iOS/macOS apps — local notifications, remote (APNs) notifications, rich notifications, notification actions, silent pushes, and notification service/content extensions. Use when working with UNUserNotificationCenter, registering for remote notifications, handling notification payloads, setting up notification categories and actions, creating rich notification content, or debugging notification delivery. Also use when working with alerts, badges, sounds, background pushes, or user notification permissions in Swift apps."
Push Notifications
Implement, review, and debug local and remote notifications on iOS/macOS using `UserNotifications` and APNs. Covers permission flow, token registration, payload structure, foreground handling, notification actions, grouping, and rich notifications. Targets iOS 26+ with Swift 6.3, backward-compatible to iOS 16 unless noted.
Keep adjacent domains separate: Live Activity `content-state` payloads belong in `activitykit`; PushKit/VoIP call pushes belong in `callkit`; App Clip ephemeral notification setup belongs in `app-clips`; long-running or scheduled background work after a silent push belongs in `background-processing`.
Contents
- [Correction Reviews](#correction-reviews)
- [Permission Flow](#permission-flow)
- [APNs Registration](#apns-registration)
- [Local Notifications](#local-notifications)
- [Remote Notification Payload](#remote-notification-payload)
- [Notification Handling](#notification-handling)
- [Notification Actions and Categories](#notification-actions-and-categories)
- [Notification Grouping](#notification-grouping)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Correction Reviews
When reviewing flawed notification proposals, explicitly name the violated contract. APNs token reviews must say token registration is independent from alert authorization, upload on every `didRegister` callback, avoid local-cache-as-truth logic, never assume token length, and treat Simulator registration failure as expected while noting `.apns` files or `simctl push` can simulate delivery. Background-push reviews must say `content-available` only, `apns-push-type: background`, `apns-priority: 5`, Remote notifications background mode, low priority, throttled, not guaranteed, not every few minutes, and bounded `didReceiveRemoteNotification` returning the correct `UIBackgroundFetchResult`. Rich-notification reviews must say service extensions require `mutable-content: 1` plus an alert payload, silent pushes do not trigger them, attachments are supported on-disk files that the system validates and stores, secrets use Keychain Sharing while App Groups are for shared files/UserDefaults, communication notifications require capability + `NSUserActivityTypes` + `INInteraction` donation + `content.updating(from:)`, and every service-extension path including attachment/download failures and `serviceExtensionTimeWillExpire()` must call the content handler exactly once with original, best-attempt, or updated content.
Permission Flow
Request notification authorization before scheduling or displaying user-visible alerts, sounds, or badges. The system prompt appears only once; subsequent calls return the stored decision. APNs token registration is separate: call `registerForRemoteNotifications()` when the app needs a device token, even if the user hasn't granted alert authorization.
import UserNotifications
@MainActor
func requestNotificationPermission() async -> Bool {
let center = UNUserNotificationCenter.current()
do {
let granted = try await center.requestAuthorization(
options: [.alert, .sound, .badge]
)
return granted
} catch {
print("Authorization request failed: \(error)")
return false
}
}Checking Current Status
Always check status before assuming permissions. The user can change settings at any time.
@MainActor
func checkNotificationStatus() async -> UNAuthorizationStatus {
let settings = await UNUserNotificationCenter.current().notificationSettings()
return settings.authorizationStatus
// .notDetermined, .denied, .authorized, .provisional, .ephemeral
}Provisional Notifications
Provisional notifications deliver quietly to the notification center without interrupting the user. The user can then choose to keep or turn them off. Use for onboarding flows where you want to demonstrate value before asking for full permission.
// Delivers silently -- no permission prompt shown to the user try await center.requestAuthorization(options: [.alert, .sound, .badge, .provisional])
Critical Alerts
Critical alerts bypass Do Not Disturb and the mute switch. Requires a special entitlement from Apple (request via developer portal). Use only for health, safety, or security scenarios.
// Requires com.apple.developer.usernotifications.critical-alerts entitlement
try await center.requestAuthorization(
options: [.alert, .sound, .badge, .criticalAlert]
)Handling Denied Permissions
When the user has denied notifications, guide them to Settings with `UIApplication.openSettingsURLString`. Do not repeatedly prompt or nag.
APNs Registration
Use `UIApplicationDelegateAdaptor` to receive the device token in a SwiftUI app. The AppDelegate callbacks are the only way to receive APNs tokens.
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
UNUserNotificationCenter.current().delegate =86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.
Repo: dpearson2699/swift-ios-skills
Other skills on swift-ios-skills.
- /accessorysetupkit
Discover and configure Bluetooth and Wi-Fi accessories using AccessorySetupKit. Use when presenting a privacy-preserving accessory picker, defining discovery descriptors for BLE or Wi-Fi devices, handling accessory session events, migrating from CoreBluetooth permission-based
Open skill - /activitykit
Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media
Open skill - /adattributionkit
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing
Open skill - /alarmkit
Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple Watch system UI. Covers AlarmManager scheduling, AlarmAttributes and AlarmPresentation, system Stop and AlarmButton secondary actions, authorization,
Open skill - /app-clips
Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store Connect experiences, size/capability constraints, NSUserActivity routing, SKOverlay promotion, App Group/keychain handoff, ephemeral notifications,
Open skill - /app-intents
Implement App Intents for Siri, Shortcuts, Spotlight, widgets, Control Center, and Apple Intelligence on iOS. Covers AppIntent actions, AppEntity and EntityQuery models, AppShortcutsProvider phrases, IndexedEntity Spotlight indexing, WidgetConfigurationIntent, SnippetIntent, and
Open skill

