Ios 当我的应用程序关闭时,我如何处理通知操作?

Ios 当我的应用程序关闭时,我如何处理通知操作?,ios,notifications,Ios,Notifications,问题摘要 我正在编写一个iOS应用程序,它发送提醒通知,让用户通过x-callback-url运行其他应用程序。如果应用程序位于前台或后台,我的一切都能正常工作,但当我的应用程序关闭时,它就无法工作 当我的应用程序关闭时,通知也会正确传递,用户可以将其关闭,或选择自定义操作通过其x-callback-url启动另一个应用程序。当用户对通知采取任何操作时,我的应用程序会正常启动 当应用程序从关闭状态直接启动时,不起作用的是触发启动x-callback-url以启动快捷方式应用程序 这是代码 这是我

问题摘要

我正在编写一个iOS应用程序,它发送提醒通知,让用户通过x-callback-url运行其他应用程序。如果应用程序位于前台或后台,我的一切都能正常工作,但当我的应用程序关闭时,它就无法工作

当我的应用程序关闭时,通知也会正确传递,用户可以将其关闭,或选择自定义操作通过其x-callback-url启动另一个应用程序。当用户对通知采取任何操作时,我的应用程序会正常启动

当应用程序从关闭状态直接启动时,不起作用的是触发启动x-callback-url以启动快捷方式应用程序

这是代码

这是我的AppDelegate中与通知相关的代码:

    // Handle what we need to after the initial application load
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Setup our custom notification options and notification category.
        // Note that The table view controller will register to handle the actual notification actions.
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) {(granted, Error) in
            if !granted {
                os_log("AppDelegate: Notification authorization NOT granted.", log: OSLog.default, type: .info)
            } else {
                os_log("AppDelegate: Notification authorization granted.", log: OSLog.default, type: .info)

                // Define our custom notification actions
                let runAction = UNNotificationAction(identifier: "RUN_SHORTCUT", title: "Run Shortcut", options: [.foreground])
                let snoozeAction = UNNotificationAction(identifier: "SNOOZE", title: "Snooze 10 Minutes", options: [])
                let skipAction = UNNotificationAction(identifier: "SKIP_SHORTCUT", title: "Skip Shortcut", options: [])

                // Define our custom notification categories
                let shortcutCategory =
                    UNNotificationCategory(identifier: "SHORTCUT_REMINDER", actions: [snoozeAction, runAction, skipAction], intentIdentifiers: [], options: .customDismissAction)
                let noshortcutCategory =
                    UNNotificationCategory(identifier: "NO_SHORTCUT_REMINDER", actions: [snoozeAction], intentIdentifiers: [], options: .customDismissAction)

                // Register the nofication category and actions with iOS
                let notificationCenter = UNUserNotificationCenter.current()
                notificationCenter.setNotificationCategories([shortcutCategory, noshortcutCategory])
                os_log("AppDelegate: Set our custom notification categories and actions.", log: OSLog.default, type: .info)

            } //endif
        } //endfunc

        return true
    }

    // Handle notifications when our app is in the background
    // Note that this isn't triggered when the notification is delivered, but rather when the user interacts with the notification
    //
    // TO-DO: THIS DOESN'T RUN THE SHORTCUT IF THE APP WAS CLOSED WHEN THE NOTIFICATION WAS RESPONDED TO!!!
    //
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {

        // Get the user info from the notification
        let userInfo = response.notification.request.content.userInfo

        // Get the specific record id that triggered this notification
        let itemID = userInfo["ITEM_ID"] as? String
        let itemTitle = userInfo["ITEM_TITLE"] as? String
        let itemShortcut = userInfo["ITEM_SHORTCUT"] as? String
        let itemURL = userInfo["ITEM_URL"] as? String

        // Handle the notification action
        print("RemindersViewController: Received notification. actionIdentifier:", response.actionIdentifier)
        switch response.actionIdentifier {

        // If user selected the Run Shortcut option or simply tapped the notification, run the associated shortcut
        case "RUN_SHORTCUT", "com.apple.UNNotificationDefaultActionIdentifier":
            os_log("RemindersViewController: Notification Action Received: RUN_SHORTCUT: %{public}@ for shortcut %{public}@", log: .default, type: .info, String(describing: itemTitle!), String(describing: itemShortcut!))
            if (itemShortcut != nil && itemShortcut != "") {
                if (itemURL != nil) {
                    print("RemindersViewController: Shortcut URL=", itemURL!)
                    let launchURL = URL(string: itemURL!)
                    if UIApplication.shared.canOpenURL(launchURL!) {
                        UIApplication.shared.open(launchURL!, options: [:], completionHandler: { (success) in
                            print("RemindersViewController: Notification Action: Run shortcut: Open url : \(success)")
                        })
                    } else {
                        let alert = UIAlertController(title: "You don't have the Shortcuts app installed", message: "Please download from the Apple App Store", preferredStyle: .alert)
                        let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                        alert.addAction(action)
                        self.present(alert, animated: true, completion: nil)
                        print("RemindersViewController: Notification Action: User doesn't have the Shortcuts app.")
                    }
                } else {
                    let alert = UIAlertController(title: "You don't have a shortcut name filled in", message: "Please fill in a shortcut name on your reminder", preferredStyle: .alert)
                    let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                    alert.addAction(action)
                    present(alert, animated: true, completion: nil)
                    print("RemindersViewController: Notification Action: No shortcut name filled in!")
                }
            }
            break

        default:
            os_log("RemindersViewController: Default action selected, which is: %{public}@. Doing nothing.", log: .default, type: .info, response.actionIdentifier)
            break
        }


        // Call the completion handler to close out the notification
        completionHandler()
    }
这是我的主表视图控制器中的代码,它是接收通知的代理:

    // Handle what we need to after the initial application load
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Setup our custom notification options and notification category.
        // Note that The table view controller will register to handle the actual notification actions.
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) {(granted, Error) in
            if !granted {
                os_log("AppDelegate: Notification authorization NOT granted.", log: OSLog.default, type: .info)
            } else {
                os_log("AppDelegate: Notification authorization granted.", log: OSLog.default, type: .info)

                // Define our custom notification actions
                let runAction = UNNotificationAction(identifier: "RUN_SHORTCUT", title: "Run Shortcut", options: [.foreground])
                let snoozeAction = UNNotificationAction(identifier: "SNOOZE", title: "Snooze 10 Minutes", options: [])
                let skipAction = UNNotificationAction(identifier: "SKIP_SHORTCUT", title: "Skip Shortcut", options: [])

                // Define our custom notification categories
                let shortcutCategory =
                    UNNotificationCategory(identifier: "SHORTCUT_REMINDER", actions: [snoozeAction, runAction, skipAction], intentIdentifiers: [], options: .customDismissAction)
                let noshortcutCategory =
                    UNNotificationCategory(identifier: "NO_SHORTCUT_REMINDER", actions: [snoozeAction], intentIdentifiers: [], options: .customDismissAction)

                // Register the nofication category and actions with iOS
                let notificationCenter = UNUserNotificationCenter.current()
                notificationCenter.setNotificationCategories([shortcutCategory, noshortcutCategory])
                os_log("AppDelegate: Set our custom notification categories and actions.", log: OSLog.default, type: .info)

            } //endif
        } //endfunc

        return true
    }

    // Handle notifications when our app is in the background
    // Note that this isn't triggered when the notification is delivered, but rather when the user interacts with the notification
    //
    // TO-DO: THIS DOESN'T RUN THE SHORTCUT IF THE APP WAS CLOSED WHEN THE NOTIFICATION WAS RESPONDED TO!!!
    //
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {

        // Get the user info from the notification
        let userInfo = response.notification.request.content.userInfo

        // Get the specific record id that triggered this notification
        let itemID = userInfo["ITEM_ID"] as? String
        let itemTitle = userInfo["ITEM_TITLE"] as? String
        let itemShortcut = userInfo["ITEM_SHORTCUT"] as? String
        let itemURL = userInfo["ITEM_URL"] as? String

        // Handle the notification action
        print("RemindersViewController: Received notification. actionIdentifier:", response.actionIdentifier)
        switch response.actionIdentifier {

        // If user selected the Run Shortcut option or simply tapped the notification, run the associated shortcut
        case "RUN_SHORTCUT", "com.apple.UNNotificationDefaultActionIdentifier":
            os_log("RemindersViewController: Notification Action Received: RUN_SHORTCUT: %{public}@ for shortcut %{public}@", log: .default, type: .info, String(describing: itemTitle!), String(describing: itemShortcut!))
            if (itemShortcut != nil && itemShortcut != "") {
                if (itemURL != nil) {
                    print("RemindersViewController: Shortcut URL=", itemURL!)
                    let launchURL = URL(string: itemURL!)
                    if UIApplication.shared.canOpenURL(launchURL!) {
                        UIApplication.shared.open(launchURL!, options: [:], completionHandler: { (success) in
                            print("RemindersViewController: Notification Action: Run shortcut: Open url : \(success)")
                        })
                    } else {
                        let alert = UIAlertController(title: "You don't have the Shortcuts app installed", message: "Please download from the Apple App Store", preferredStyle: .alert)
                        let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                        alert.addAction(action)
                        self.present(alert, animated: true, completion: nil)
                        print("RemindersViewController: Notification Action: User doesn't have the Shortcuts app.")
                    }
                } else {
                    let alert = UIAlertController(title: "You don't have a shortcut name filled in", message: "Please fill in a shortcut name on your reminder", preferredStyle: .alert)
                    let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                    alert.addAction(action)
                    present(alert, animated: true, completion: nil)
                    print("RemindersViewController: Notification Action: No shortcut name filled in!")
                }
            }
            break

        default:
            os_log("RemindersViewController: Default action selected, which is: %{public}@. Doing nothing.", log: .default, type: .info, response.actionIdentifier)
            break
        }


        // Call the completion handler to close out the notification
        completionHandler()
    }
预期和实际结果


我希望当应用程序由于用户与通知交互而从关闭状态启动时,自定义的“运行快捷方式”操作应启动快捷方式应用程序,其x-callback-url存储在通知用户数据中。

作为更新:我现在已使用.前台和.Authentication指定了运行快捷方式操作,以确保应用程序将被加载,并且用户必须解锁其设备。我想问题可能是,当设备被锁定时,应用程序无法启动另一个应用程序。但是,唉,这并没有解决任何问题。由于某些原因,如果在执行通知时关闭了我的应用程序,则该应用程序不会启动其他应用程序。我也想这样做。当用户清除通知时,我想获取userInfo数据,并将其保存在数据库的某个地方。但问题是当用户清除通知时,当我的应用程序关闭/终止时。我错过了服务器发送的通知中的信息。那么,我如何恢复这种情况,或者如何检查清除通知操作?