在推送通知 Swift 2 AppDelegate 上加载特定的 viewController

Posted

技术标签:

【中文标题】在推送通知 Swift 2 AppDelegate 上加载特定的 viewController【英文标题】:Load a specific viewController on push notification Swift 2 AppDelegate 【发布时间】:2016-01-08 10:44:55 【问题描述】:

我想打开一个特定的视图控制器(一个隐藏的视图控制器,因为它只有在收到某个推送通知时才能访问(它不能通过标签栏访问))并且我已经能够做到这一点,但我面临有问题..

我的应用有一个名为RootViewController 的自定义标签栏控制器。当您单击具有特殊值的通知时,它会显示一个警报视图,询问用户是否要打开通知。

通知触发将特定的视图控制器带到前面,但 问题是我无法再访问标签栏了。

我不知道如何实现。

这是我在AppDelegate.m中的代码:

var presentedVC = self.window?.rootViewController as? UINavigationController
while (presentedVC!.navigationController != nil)  
    presentedVC = presentedVC!.navigationController

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewControllerWithIdentifier("PushNotificationView") as? NotTestViewController

destinationViewController?.url = self.url!
presentedVC?.presentViewController(destinationViewController!, animated: true, completion: nil)

)
)
alertCtrl.addAction(UIAlertAction(title: "Cancelar", style: .Destructive, handler: nil))

此代码可以正常工作,但不能实现所需的行为。

任何想法我缺少什么?

非常感谢

编辑

我已将RAMTabBarAnimationController 更改为TabBarController,因为RAMTabBarAnimationController 不继承自TabBarController。但我仍然看到相同的行为。

【问题讨论】:

presentedVC?.tabBarController?.selectedViewController?.pushViewController(destinationViewController!, animated: true) 怎么样? 使用 window.rootViewController presentViewController .....请记住 ....需要推送通知才能运行的应用程序将被拒绝 Presenting a specific view controller from AppDelegate的可能重复 嗨@anishparajuli,你提到的解决方案是我已经拥有的。我首先实例化 rootViewController var presentedVC = self.window?.rootViewController as? UITabBarController 并获取目标视图控制器 let destinationViewController = storyboard.instantiateViewControllerWithIdentifier("PushNotificationView") as? NotTestViewController 最后你提到的 presentedVC?.selectedViewController!.presentViewController(destinationViewController!, animated: true, completion: nil) 它显示但标签栏在下面:/(ps:我的应用程序在没有通知的情况下工作):) 【参考方案1】:

我想回答我自己的问题,因为我认为也许有人面临同样的情况,我不得不感谢@Muneeba

嗯,首先你必须知道你的远程推送通知是否需要进行后台获取,这很重要,因为如果是这样,didReceiveRemoteNotification 会被调用两次(第一次是当你点击通知警报时,第二次是当它打开应用程序),因此您必须注意这一点。

在我的情况下,我没有进行后台提取,所以我的 content-available:false 标志设置为 false。

接下来要做的是将您想要的["key":value] 添加到通知负载中,以了解您是否要打开特定的视图控制器。

管理是否打开视图控制器。

在我的应用程序中,我想打开一个警报控件弹出窗口,始终显示推送通知的正文(带有确定按钮),并且只有在设置了特定值时才打开一个警报控件,并向用户询问他是否想要打开到达的新内容(通常此内容是基于 Web 的内容,打开嵌入在视图控制器中的 Web 视图)

didReceiveRemoteNotification

if let mensaje = userInfo["m"] as? String 
// Here is where I know if the value is set in the notification payload
 let alertCtrl = UIAlertController(title: titulo, message: mensaje as String, preferredStyle: UIAlertControllerStyle.Alert)
 if url == nil 
   alertCtrl.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
  else 
 alertCtrl.addAction(UIAlertAction(title: "Ver receta", style: .Default, handler: 
  action in

      let storyboard = UIStoryboard(name: "Main", bundle: nil)
      //self.window?.rootViewController = storyboard.instantiateViewControllerWithIdentifier("TabbedController") as! UITabBarController
      let navigationController = storyboard.instantiateViewControllerWithIdentifier("pushNotificationNavigation") as! UINavigationController
      let dVC:NotTestViewController = navigationController.topViewController as! NotTestViewController
      // This is for passing the URL to the view Controller
      dVC.url = self.url!
      self.window?.rootViewController?.presentViewController(navigationController, animated: true, completion: )

      )
      )
      alertCtrl.addAction(UIAlertAction(title: "Cancelar", style: .Destructive, handler: nil))
   
   // Find the presented VC...
   var presentedVC = self.window?.rootViewController
   while (presentedVC!.presentedViewController != nil)  
      presentedVC = presentedVC!.presentedViewController
      
      presentedVC!.presentViewController(alertCtrl, animated: true, completion: nil)

      handler(UIBackgroundFetchResult.NoData)
 

【讨论】:

嗨@Nilesh,您看到的网址是我正在使用的 NotTestViewController 的变量。在 NotTestViewController 中,我得到了一个 webView,它包含一个 url:String 变量。当我从 AppDelegate 中调用该控制器时,我正在传递有效负载中通知随附的 URL。【参考方案2】:

您的RAMAnimatedTabBarController 继承了哪个类?如果它继承了UIViewController/UITabbarController 然后取一个UINavigationController 并将其rootViewController 设置为您的RAMAnimatedTabBarController 实例,然后将其分配为窗口的rootViewController 并为此UINavigationController 设置navigationBar 隐藏,当您想要推送到特定的 Controller 这样做

var presentedVC = self.window?.rootViewController as? UINavigationController
presentedVC(yourdesiredController, animated: true)

【讨论】:

我已经将 RAMAnimatedTabBarController 更改为 UITarbBarController 因为你所说的(RAMAnimatedTabBar 不继承自 UITabBarController),我无法在新视图上方显示标签栏。 Cannot call value of non-function type 'UINavigationController? 尝试时 presentedVC(destinationViewController!, animated: true) 您想在您的特定视图上显示标签?告诉我你的完整要求。同时使用新代码更新问题。 嗨@Muneeba这是WebView,我只想在通知带有特定有效负载时显示,我想显示标签栏,因为如果不是你不能摆脱webview,你也无法导航应用程序。此 web 视图仅显示在 didReceiveRemoteNotification 的 appdelegate 中 您是否在 UIViewController 的 xib 中添加了 WebView?如果是这样,请实施我说的解决方案。并且在推送之前使该 UINavigationController 的导航栏不隐藏,因此现在您将拥有来自 WebView 的后退选项。并且在该控制器的 viewDidDisappear 中不要忘记再次隐藏导航栏。 移除 while 代码块。 presentVC 本身就是一个navigationController 实例,不需要对presentedVC.navigationController。

以上是关于在推送通知 Swift 2 AppDelegate 上加载特定的 viewController的主要内容,如果未能解决你的问题,请参考以下文章

无法在 iOS8 上设置交互式推送通知

Swift FIRMessaging 在注册时发送推送通知请求

推送通知无法正常工作,当应用程序在后台时,Swift

UILocalNotifcation 未在 swift 2.0 中触发

从 appdelegate swift 访问 UIwebview

Swift:单击推送通知操作按钮时在文本字段中写入并处理它