The Simulator is great for checking how your app handles a notification. Drag an .apns file onto it, or run xcrun simctl push , and the banner appears. But that never touches Apple's servers, so it can't catch the problems that actually break push in production: a wrong environment, a topic that doesn't match your bundle ID, or an auth key that isn't allowed to send.
This guide walks through sending a real push to a real iPhone through APNs, with nothing but Node.js and a .p8 key. No third-party service, no backend.
1. Get a device token
Add the Push Notifications capability to your target in Xcode (Signing & Capabilities), then register and log the token:
import UIKit import UserNotifications
class AppDelegate : NSObject , UIApplicationDelegate { func application ( _ application : UIApplication , didFinishLaunchingWithOptions launchOptions : [ UIApplication . LaunchOptionsKey : Any ]? = nil ) -> Bool { UNUserNotificationCenter . current () . requestAuthorization ( options : [ . alert , . sound , .…