iOS Swift:点击本地通知操作唤醒后台应用问题求助
Hey there! Let's break down why your app isn't waking up when you tap the "Open App" action from a local notification while it's in the background or inactive state, and how to fix it.
The Core Problem with Your Current Code
Your current canOpenURL + openURL approach is meant for launching other apps or external URLs—not waking up your own app. This method won't work here because iOS has built-in mechanisms to bring your app to the foreground when a notification action is triggered, and trying to open your own URL scheme this way in the background is unnecessary (and often blocked by system restrictions).
Step 1: Fix Your Notification Action Configuration
The key mistake is likely missing the .foreground option when creating your "Open App" notification action. This option tells iOS to automatically bring your app to the foreground when the action is tapped.
Here's how to create the action correctly:
// Create the "Open App" action with the foreground option let openAppAction = UNNotificationAction( identifier: "com.yourapp.openApp", // Use a unique identifier matching your setup title: "打开应用", options: [.foreground] // This is the critical line! ) // Add the action to a notification category let notificationCategory = UNNotificationCategory( identifier: "com.yourapp.mainCategory", actions: [openAppAction, replyAction, cancelAction], // Include your other existing actions intentIdentifiers: [], options: [] ) // Register the category with UNUserNotificationCenter UNUserNotificationCenter.current().setNotificationCategories([notificationCategory])
Step 2: Clean Up Your didReceive Logic
Once you've added the .foreground option, iOS will automatically wake your app to the foreground when the action is tapped. You don't need the openURL call anymore—just handle any custom logic you need, and make sure to call the completion handler:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let actionId = response.actionIdentifier switch actionId { case "com.yourapp.openApp": // Add any foreground setup logic here (e.g., navigate to a specific screen) // iOS already brings the app to the foreground automatically case "com.yourapp.reply": // Handle the reply action let replyText = (response as? UNTextInputNotificationResponse)?.userText ?? "" print("User replied: \(replyText)") case "com.yourapp.cancel": // Handle the cancel action print("User canceled the notification") default: break } completionHandler() // Always call this to notify iOS you're done processing }
Step 3: Handle App Launch from Terminated State
If your app was completely closed (not just in the background), tapping the "Open App" action will launch the app from scratch. You'll need to handle this in didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Check if the app was launched from a local notification if let notificationUserInfo = launchOptions?[.localNotification] as? [String: Any] { // Handle the notification logic (e.g., navigate to a specific screen) print("Launched from local notification: \(notificationUserInfo)") } // Don't forget to set up UNUserNotificationCenter delegate here if you haven't UNUserNotificationCenter.current().delegate = self return true }
Quick Recap
- The
.foregroundoption on your notification action is what tells iOS to wake your app. - Ditch the
openURLcall—it's not designed for waking your own app. - Make sure to register your notification category correctly.
- Handle the launch-from-terminated case in
didFinishLaunchingWithOptions.
内容的提问来源于stack exchange,提问作者Ashh

