FI
ForgePush

Getting Started

ForgePush is a collection of four focused libraries for iOS push notification management. Use them all together or pick only what you need.

Libraries

ForgePushPermission

Request authorization, check status, and open Settings.

ForgePushToken

Bridge APNs registration callbacks into a token property and async stream.

ForgeSilentPush

Route background/silent pushes to registered handlers with aggregate result reporting.

ForgeVisiblePush

Route foreground and tapped notification responses to the appropriate handler.

Requirements

  • iOS 18+
  • Swift 6.3+ (Xcode 26 or later)

Installation

AppDelegate Wiring

All four libraries connect through standard UIApplicationDelegate and UNUserNotificationCenterDelegate callbacks. Wire them up once in your AppDelegate.

AppDelegate.swift
import UIKit
import ForgePushPermission
import ForgePushToken
import ForgeSilentPush
import ForgeVisiblePush

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    let tokenManager = PushTokenManager()
    let silentRouter = SilentPushRouter(
        connectivity: connectivityObserver,
        protectedData: protectedDataObserver
    )
    let visibleRouter = VisiblePushRouter(
        connectivity: connectivityObserver,
        protectedData: protectedDataObserver
    )

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Add handlers
        silentRouter.addHandler(TaskSyncHandler())
        visibleRouter.addHandler(TaskTappedHandler())

        // Request permission and register for remote notifications
        Task {
            let permission = PushPermission()
            try await permission.request()
            await tokenManager.registerForRemoteNotifications()
        }

        return true
    }

    func application(_ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        tokenManager.didRegister(deviceToken: deviceToken)
    }

    func application(_ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error) {
        tokenManager.didFailToRegister(error: error)
    }

    func application(_ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable: Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        silentRouter.handlePush(payload: userInfo, completionHandler: completionHandler)
    }
}

Tip: When using ForgeInject, inject PushTokenManager, SilentPushRouter, and VisiblePushRouter as singletons and resolve them wherever you need access. See the With ForgeInject example.