Swift IOS:从通知打开应用程序时调用 UIviewController 的特定功能
Posted
技术标签:
【中文标题】Swift IOS:从通知打开应用程序时调用 UIviewController 的特定功能【英文标题】:Swift IOS: Call Specific function of UIviewController when open app from notification 【发布时间】:2019-02-26 12:00:05 【问题描述】:我想在应用程序打开时通过点击通知调用onDidReceiveNotification
函数。 (ViewController
是第一个视图控制器,根视图控制器)
当应用程序打开或在后台运行正常,但是当应用程序未打开或在后台(不在内存中)并点击打开应用程序时onDidReceiveNotification
函数未被调用,
当应用程序通过点击推送通知打开时,我应该怎么做才能调用onDidReceiveNotification
函数
ViewController.swift
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
NotificationCenter.default.removeObserver(self, name: .didReceiveAlert, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.onDidReceiveNotification(_:)), name: .didReceiveAlert, object: nil)
@objc func onDidReceiveNotification(_ notification:Notification)
print("Received Notification")
AppDelegate.swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
NotificationCenter.default.post(name: .didReceiveAlert, object: nil)
【问题讨论】:
我认为这是预期的行为,如果应用程序关闭,您需要检查 appdelegate 中didFinishLaunchingWithOptions
中的 launchOptions
方法以获取收到的通知详细信息。
didReceiveRemoteNotification 在应用关闭并使用通知打开时调用
查看let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any]
的应用启动远程通知
好的,例如我已经签入了launchOptions,我知道应用程序已使用通知打开,但是之后如何在视图控制器中调用我的函数“onDidReceiveNotification”
【参考方案1】:
当应用程序打开或在后台调用 NotificationCenter.defalut.post
时,当应用程序终止/关闭并使用通知打开时,获取实例并通过菜单调用 onDidReceiveAlert
函数,请参见以下代码。
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
if application.applicationState == .background || application.applicationState == .active
NotificationCenter.default.post(name: .didReceiveAlert, object: nil)
else
let nav = window?.rootViewController as! UINavigationController
let mainVC = nav.viewControllers.first as! ViewController
mainVC.onDidReceiveAlert(nil)
或者直接从UINavigationController
栈中获取ViewController
实例,直接调用ViewController
的函数(Notification Observer不需要)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
let nav = window?.rootViewController as! UINavigationController
let mainVC = nav.viewControllers.first as! ViewController
mainVC.onDidReceiveAlert(nil)
使用可选参数创建函数,使用以下代码。
@objc func onDidReceiveAlert(_ notification:Notification? = nil)
print("Received Notification")
【讨论】:
【参考方案2】:试试下面的代码
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any]
//call your notification method from here
NotificationCenter.default.post(name: .didReceiveAlert, object: nil)
希望您在所有情况下都只需要调用didReceiveAlert
通知
【讨论】:
【参考方案3】:在 AppDelegate 中检查您是否在 didReceiveRemoteNotification 中获得了有效负载。从那里您可以编写代码以推送到特定页面。
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any])
// Print full message.
print(userInfo)
pushToPage(data: userInfo)
func pushToPage(data:[AnyHashable : Any])
print("Push notification received: \(data)")
if let aps = data["aps"] as? NSDictionary
print(aps)
【讨论】:
【参考方案4】:当应用处于非活动状态并且用户点击通知时。在这种情况下,只有一个选项来管理通知。
试试这个
在全局类中创建一个变量,以便您可以从任何地方访问它。
Ex在AppDelegate中创建变量
var isNotificationTap : Bool = false
然后检查launchOptions
,如果launchOptions
可用,则设置标志
if launchOptions != nil
if let userInfo = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? [String : AnyObject]
if let dic = userInfo["body"] as? [String : AnyObject]
if let pushType = dic["push_type"] as? String
//Set Flag or any key in global file to identify that you tap on notification
self.isNotifcaionTap = true
然后只需检查 ViewController 中的标志。
class ViewController : UIViewController
override func viewDidLoad()
super.viewDidLoad()
if self.isNotificationTap
print("Received Notification")
//You can work with your notificaiton in inActive state
【讨论】:
我不想使用全局变量,这是一种非常低质量的方法,有没有其他方法 推送通知处于非活动状态的主要问题是我们只有在 didFinishLauching 启动选项上跟踪非活动通知点击的选项,并且我们没有 rootViewController 来管理通知流。所以我们只能选择设置 key 或 flag 来管理。以上是关于Swift IOS:从通知打开应用程序时调用 UIviewController 的特定功能的主要内容,如果未能解决你的问题,请参考以下文章
iOS Swift 从推送通知以编程方式导航到某些 ViewController