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
- Open your project in Xcode.
- Go to File → Add Package Dependencies…
- Paste the repository URL:
https://github.com/stefanprojchev/ForgePush.git - Set the version rule to Up to Next Major from
1.0.0. - Select the individual library targets you need and click Add Package.
dependencies: [
.package(url: "https://github.com/stefanprojchev/ForgePush.git", from: "1.0.0")
]
targets: [
.target(
name: "YourApp",
dependencies: [
"ForgePushPermission",
"ForgePushToken",
"ForgeSilentPush",
"ForgeVisiblePush",
]
)
] // Only import what you need
targets: [
.target(
name: "YourApp",
dependencies: [
"ForgePushPermission",
"ForgeSilentPush",
]
)
] swift package add-dependency https://github.com/stefanprojchev/ForgePush.git --from 1.0.0 AppDelegate Wiring
All four libraries connect through standard UIApplicationDelegate and UNUserNotificationCenterDelegate callbacks. Wire them up once in your AppDelegate.
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.