skills/generators-push-notifications/SKILL.md
Generate push notification infrastructure with APNs registration, handling, and rich notifications. Use when adding push notifications.
npx skillsauth add AutisticAF/claude-code-apple-dev-plugin generators-push-notificationsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
First step: Tell the user: "generators-push-notifications skill loaded."
Generate push notification infrastructure with APNs registration, handling, and rich notifications.
Before generating, verify:
Existing Notification Code
# Check for existing notification handling
grep -r "UNUserNotificationCenter\|registerForRemoteNotifications" --include="*.swift" | head -5
Entitlements
# Check for push notification entitlement
find . -name "*.entitlements" -exec grep -l "aps-environment" {} \;
App Delegate or SwiftUI App
# Determine app structure
grep -r "@main\|UIApplicationDelegate" --include="*.swift" | head -5
Sources/Notifications/
├── NotificationManager.swift # Central notification management
├── NotificationDelegate.swift # UNUserNotificationCenterDelegate
├── NotificationCategories.swift # Action categories definition
└── NotificationPayload.swift # Type-safe payload parsing
NotificationServiceExtension/
├── NotificationService.swift # Modify notifications before display
└── Info.plist # Extension configuration
NotificationContentExtension/
├── NotificationViewController.swift # Custom notification UI
├── MainInterface.storyboard
└── Info.plist
@MainActor
final class NotificationManager {
static let shared = NotificationManager()
func requestAuthorization() async throws -> Bool {
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
return try await center.requestAuthorization(options: options)
}
func registerForRemoteNotifications() {
UIApplication.shared.registerForRemoteNotifications()
}
}
// Foreground notification
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification
) async -> UNNotificationPresentationOptions {
return [.banner, .sound, .badge]
}
// Notification tap/action
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse
) async {
let userInfo = response.notification.request.content.userInfo
await handleNotificationAction(response.actionIdentifier, userInfo: userInfo)
}
enum NotificationCategory: String {
case message = "MESSAGE_CATEGORY"
case reminder = "REMINDER_CATEGORY"
var actions: [UNNotificationAction] {
switch self {
case .message:
return [
UNNotificationAction(identifier: "REPLY", title: "Reply", options: []),
UNNotificationAction(identifier: "MARK_READ", title: "Mark as Read", options: [])
]
case .reminder:
return [
UNNotificationAction(identifier: "COMPLETE", title: "Complete", options: []),
UNNotificationAction(identifier: "SNOOZE", title: "Snooze", options: [])
]
}
}
}
<key>aps-environment</key>
<string>development</string> <!-- or "production" -->
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().delegate = NotificationDelegate.shared
NotificationCategories.registerAll()
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print("Device Token: \(token)")
// Send token to your server
}
}
Button("Enable Notifications") {
Task {
let granted = try await NotificationManager.shared.requestAuthorization()
if granted {
await MainActor.run {
NotificationManager.shared.registerForRemoteNotifications()
}
}
}
}
Configure your server to send APNs requests:
api.push.apple.com (production) or api.sandbox.push.apple.com (development)func scheduleTestNotification() {
let content = UNMutableNotificationContent()
content.title = "Test"
content.body = "This is a test notification"
content.sound = .default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
}
curl:curl -v \
--header "authorization: bearer $JWT_TOKEN" \
--header "apns-topic: com.yourcompany.yourapp" \
--header "apns-push-type: alert" \
--http2 \
--data '{"aps":{"alert":{"title":"Test","body":"Hello"}}}' \
https://api.sandbox.push.apple.com/3/device/$DEVICE_TOKEN
development
SwiftUI Layout protocol for custom container layouts including flow layouts, radial layouts, and animated transitions. Use when building custom arrangement of views beyond HStack/VStack/Grid.
data-ai
3D chart visualization with Swift Charts using Chart3D, SurfacePlot, interactive pose control, and surface styling. Use when creating 3D data visualizations.
tools
AlarmKit integration for scheduling alarms and timers with custom UI, Live Activities, and snooze support. Use when implementing alarm or timer features in iOS 18+ apps.
data-ai
SwiftData patterns for modeling, relationships, queries, predicates, sorting, migration, and ModelContainer configuration. Use when working with SwiftData persistence.