【问题标题】:Launch app from local notification in iOS 10从 iOS 10 中的本地通知启动应用程序
【发布时间】:2017-09-16 21:28:39
【问题描述】:

我正在尝试使用 iOS 10 中本地通知中的操作来实现应用启动(从非活动状态)。

我已关注Launch a local notification at a specific time in iOS,应用程序启动正常以响应本地通知。但是我想要从这里执行一个操作以响应通知中的数据。

在 iOS 8 和 9 中,我在 AppDelegate 中进行了设置

func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
    if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
        NotificationCenter.default.post(name: Notification.Name(rawValue: "noteName", object: notification.alertBody)

观察者在 ViewController 中捕捉到它

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.txtFromNotifier), name: NSNotification.Name(rawValue: "noteName", object: nil)

现在在 iOS 10 中的 AppDelegate 中:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    // Determine the user action
    switch response.actionIdentifier {
    case UNNotificationDismissActionIdentifier:
        print("Dismiss Action")
    case UNNotificationDefaultActionIdentifier:
        print("Default")
        // do something here

我无法找到如何从 UNNotification 默认操作(启动后在控制台中打印“默认”)传递参数并在 ViewController 中执行 txtFromNotifier 函数。尝试使用 NotificationCenter post / addObserver 组合在应用程序处于后台时有效,但在应用程序处于非活动状态时无法到达那里。

有什么想法吗?

【问题讨论】:

  • 我想通了,但我什至无法回答我自己的问题。
  • 我遇到了类似的问题。在您的接收视图控制器中调用 addObserver 之前,您的解决方案是否与广播通知有关?
  • @IanLeatherbury 是的。 IIRC 在观察者加载到 ViewController 之前,用户通知发生在 AppDelegate 中。我找到了一些想法,但是时间太久了,我忘记了在哪里。本质上,我在 AppDelegate 中延迟包装了通知帖子。

标签: ios swift unnotificationrequest


【解决方案1】:

我找到了解决方案。我对通知广播进行了延迟。我的 AppDelegate 现在看起来像这样。在 didFinishLaunchingWithOptions 中选择通知中心:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if #available(iOS 10.0, *) {
        let center = UNUserNotificationCenter.current()
        center.delegate = self
        let options: UNAuthorizationOptions = [.alert, .badge, .sound]
        center.requestAuthorization(options: options) {
            (granted, error) in
            if !granted {
                print("Something went wrong")
            }
        }
    } else {
        application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.alert , .badge , .sound], categories: nil))
    }
    return true
}

在 didReceiveNotification 中我选择了 iOS 10...

func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
    if #available(iOS 10.0, *) {
        // different notification centre for iOS 10, see @available below
    } else {
        if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
            runAfterDelay(2.0) {  // 2 second delay, not sure if needed but doesn't seem to hurt - runAfterDelay function is below
                NotificationCenter.default.post(name: Notification.Name(rawValue: NSLocalizedString("ticker_notification_name", comment: "")), object: notification.alertBody)
            }
        } /*else {
         // handle the local notification when the app is open, if needed
         } */
    }
}

并使用 @available 选项为 iOS 10 选择:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // Determine the user action
    switch response.actionIdentifier {
    case UNNotificationDismissActionIdentifier:
        print("Dismiss Action")
    case UNNotificationDefaultActionIdentifier:
        print("Default")
        runAfterDelay(3.0) {  // 3 second delay to give observer time to load. 3 seconds is arbitrary. runAfterDelay function is below
            NotificationCenter.default.post(name: Notification.Name(rawValue: NSLocalizedString("ticker_notification_name", comment: "")), object: response)  // .body
        }
    case "Snooze":
        print("Snooze")
    case "Delete":
        print("Delete")
    default:
        print("Unknown action")
    }
    completionHandler()
}

还有让观察者有时间穿上袜子的 runAfterDelay 函数:

func runAfterDelay(_ delay: Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

我认为我不必对观察者进行任何更改 - 我在修订历史记录中看不到任何更改,它看起来与原始问题中的 addObserver 方法相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多