在点击本地通知时打开特定视图控制器

时间:2017-12-09 23:47:07

标签: ios uiviewcontroller uilocalnotification

标题说明了一切。我已经通过了一些试图整理解决方案的帖子,但没有运气..

我有一个通知,其名称我不确定......

let request = UNNotificationRequest(identifier: "timerDone", content: content, trigger: trigger)

q1:名称是timerDone

viewDidLoad()中的

NotificationCenter.default.addObserver(self,
                                                         selector: "SomeNotificationAct:",
                                                         name: NSNotification.Name(rawValue: "timerDone"),
                                                         object: nil)

然后我有这个方法:

@objc func SomeNotificationAct(notification: NSNotification){
        DispatchQueue.main.async() {
            self.performSegue(withIdentifier: "NotificationView", sender: self)
        }
    }

AppDelegate.swift

private func application(application: UIApplication, didReceiveRemoteNotification userInfo: Any?){

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SomeNotification"), object:nil)
}

任何想法如何做到这一点?提前谢谢!

更新:@Sh_Khan

首先,我正在使用swift进行编码,我尝试将代码从obj-c转换为swift:

if (launchOptions![UIApplicationLaunchOptionsKey.localNotification] != nil)
{
    var notification =
        launchOptions![UIApplicationLaunchOptionsKey.localNotification]
    [self application:application didReceiveLocalNotification:notification]; //how to translate?
}

最后一行应该被翻译成什么?

当你写道:

应该在didReceiveLocalNotification方法的用户默认值中存储一个布尔变量,并在rootViewcontroller的viewDidAppear方法中检查它以生成segue,然后将其设为false,因为只有当app在前台或后台时,notificationCenter才会起作用它尚未暂停

假设布尔值为notiView,我们在收到本地通知时将其设置为true,因此segue将指向不同的视图控制器。这是你的意思吗?

2 个答案:

答案 0 :(得分:1)

我发现用户通知的文档有点令人困惑和不完整。这些教程比大多数其他Apple框架更好。但是,这些教程大多不完整,并假设每个应用程序都在AppDelegate中实现通知中心委托。不!

对于在视图控制器中处理通知委托(而不是在AppDelegate中)的许多应用程序,需要将视图控制器设置为AppDelegate didFinishLaunchingWithOptions方法内的用户通知中心委托。否则,当您的应用从后台模式启动时,通知代理将无法看到您的通知触发。通知触发后加载视图控制器。在视图控制器完成加载后,您需要一种方法来启动委托方法。

例如:假设您使用拆分视图控制器作为应用程序的初始视图控制器,并且已将拆分VC的主视图控制器实现为通知委托,则需要让UNUserNotificationCenter知道当你的应用程序启动时,master VC就是它的委托(不像大多数教程所建议的那样在主VC的viewDidLoad()里面)。例如,

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        ...
        let splitViewController = window!.rootViewController as! UISplitViewController
        ...
        if #available(iOS 10.0, *) {
            if let masterViewController = splitViewController.viewControllers.first as? MasterViewController {
                UNUserNotificationCenter.current().delegate = masterViewController
            }
        }
    }

这将允许iOS在您的应用程序冷启动或从后台模式启动主VC后调用您的通知委托方法。

此外,如果您需要主VC知道它已加载,因为用户通知触发(而不是正常加载),您将使用NSUserDefaults传达此信息。因此,AppDelegate看起来如下:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...
    let splitViewController = window!.rootViewController as! UISplitViewController
    ...
    if #available(iOS 10.0, *) {
        if let _ = launchOptions?[UIApplicationLaunchOptionsKey.localNotification] {
            UserDefaults.standard.set("yes", forKey: kMyAppLaunchedByUserNotification)
            UserDefaults.standard.synchronize()
        }
        if let masterViewController = splitViewController.viewControllers.first as? MasterViewController {
            UNUserNotificationCenter.current().delegate = masterViewController
        }
    }
}

其中kMyAppLaunchedByUserNotification是用于与主VC通信的密钥。在Master View Controller的viewDidAppear()中,您将检查User Defaults以查看是否因为通知而加载了它。

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if #available(iOS 10.0, *) {
        if let _ = UserDefaults.standard.object(forKey: kMyAppLaunchedByUserNotification) {
            UserDefaults.standard.removeObject(forKey: kMyAppLaunchedByUserNotification)
            UserDefaults.standard.synchronize()
            //Handle any special thing that you need to do when your app is launched from User notification as opposed to regular app launch here
            // NOTE: the notification delegate methods will be called after viewDidAppear() regardless of you doing any special thing here because you told iOS already in AppDelegate didFinishLaunchingWithOptions
        }
    }
}

我希望这会对你有所帮助。

答案 1 :(得分:0)

如果该应用已关闭且您点按了本地通知,请在 didFinishLaunchingWithOptions 方法

中进行检查

/// Objective-C

if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] != nil)
{
  UILocalNotification *notification =
  launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
 [self application:application didReceiveLocalNotification:notification];
}

/// Swift

if (launchOptions![UIApplicationLaunchOptionsKey.localNotification] != nil)
{     

    var notification =
    launchOptions![UIApplicationLaunchOptionsKey.localNotification]

   self.application(application, didReceive: notification)
}

注意:尚未调用rootViewcontroller的 viewDidLoad ,因此不会触发观察者,因此您应该在 didReceiveLocalNotification 方法并在rootView控制器的 viewDidAppear 方法中检查它以生成segue,然后将其设为 false ,因为只有当app在<时,notificationCenter才能工作strong>前景或后台,如果它尚未暂停。 。

更新:@Shi_Zhang

是的,这就是我的意思