You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 9.2中PushKit问题:无法获取设备令牌

Fixing PushKit Device Token Issue in Xcode 9.2

Hey there, let's work through why you're not receiving the PushKit device token in your Xcode 9.2 project. Your current code is missing some critical setup steps for PushKit—let's break it down and fix it.

What's Missing in Your Implementation?

  • You only registered for standard remote notifications, but PushKit requires its own dedicated registry setup
  • There's no initialization or configuration of the PKPushRegistry instance (this is the core component for PushKit)
  • You haven't implemented the required PushKit delegate methods to capture the device token

Corrected Code with Explanations

import UIKit
import PushKit
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, PKPushRegistryDelegate, UNUserNotificationCenterDelegate {
    var window: UIWindow?
    // Keep the registry as a class property to avoid premature deallocation
    var pushRegistry: PKPushRegistry!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Set up notification authorization first, and assign the delegate to handle foreground alerts
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
            if let error = error {
                print("Notification auth error: \(error.localizedDescription)")
            }
            print(granted ? "Notification access granted" : "Notification access denied")
        }
        
        // Initialize and configure PushKit
        setupPushKit()
        
        NSLog("PushKit setup started...")
        return true
    }
    
    private func setupPushKit() {
        // Create the registry using the main queue (you can use a background queue if preferred)
        pushRegistry = PKPushRegistry(queue: DispatchQueue.main)
        // Assign the delegate to receive PushKit callbacks
        pushRegistry.delegate = self
        // Specify the push type—.voIP is the most common use case for PushKit (higher priority pushes)
        pushRegistry.desiredPushTypes = [.voIP]
    }
    
    // MARK: - PKPushRegistryDelegate Methods
    // This method fires when the PushKit token is successfully retrieved
    func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
        // Convert the raw token data to a hex string (format your backend expects)
        let deviceToken = pushCredentials.token.map { String(format: "%02.2hhx", $0) }.joined()
        NSLog("Got PushKit Device Token: \(deviceToken)")
        // Send this token to your backend server to send pushes later
    }
    
    // Handle token invalidation (e.g., when the user reinstalls the app)
    func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
        NSLog("PushKit token invalidated for type: \(type.rawValue)")
        // Update your backend to remove this invalid token
    }
    
    // Optional: Handle incoming PushKit notifications (for VOIP, this wakes up your app)
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        NSLog("Received PushKit payload: \(payload.dictionaryPayload)")
        // Process the notification content here (e.g., show an alert, start a VOIP call)
        completion()
    }
    
    // MARK: - UNUserNotificationCenterDelegate
    // Show notifications when the app is in the foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.badge, .alert, .sound])
    }
}

Key Things to Remember

  • PushKit Purpose: PushKit is built for high-priority use cases like VOIP calls—it can wake up your app even if it's terminated. If you just need standard remote notifications, you don't need PushKit; use the didRegisterForRemoteNotificationsWithDeviceToken method from UIApplicationDelegate instead.
  • Project Capabilities: Make sure your Xcode project has the Push Notifications capability enabled. If you're using VOIP pushes, also enable the Voice over IP capability.
  • Testing: PushKit tokens only work on real iOS devices—simulators don't support PushKit functionality.
  • Registry Persistence: The PKPushRegistry must be a class property (not a local variable) so it doesn't get deallocated before the token is delivered.

内容的提问来源于stack exchange,提问作者Rock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:25:27