如何在收到 iOS 推送通知时打开通知视图控制器?
How to Open a Notification view controller when a iOS push notification is received?
我在 swift 4.2
工作,从 FireBase
收到推送通知。当我点击 Notification
时,它会转到主页。但是我想去 Notification
页面。
这是Swift4.2
、Xcode 9.3
、iOS 12.1
。过去,我尝试过但没有同时使用 Foreground 和 InActive 应用程序
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
UINavigationBar.appearance().barTintColor = UIColor(red: 0/255.0, green: 85/255.0, blue: 127/255.0, alpha: 1)
UINavigationBar.appearance().tintColor = UIColor.white
// UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,NSAttributedString.Key.font: UIFont(name: "Roboto-Medium", size: 16)!]
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -60), for:UIBarMetrics.default)
UINavigationBar.appearance().isTranslucent = false
UIApplication.shared.statusBarStyle = .lightContent
IQKeyboardManager .shared().isEnabled = true
IQKeyboardManager .shared().shouldResignOnTouchOutside = true
IQKeyboardManager .shared().isEnableAutoToolbar = false
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {
// If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions
let aps = notification["aps"] as! [String: AnyObject]
UIApplication.shared.applicationIconBadgeNumber = 0
}
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
let mainview = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let nav = UINavigationController.init(rootViewController: mainview)
SideMenu = LGSideMenuController.init(rootViewController: nav)
SideMenuView = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "SideMenuViewController") as! SideMenuViewController
SideMenu.rightViewStatusBarVisibleOptions = .onAll
let rect = SideMenuView.view.frame;
SideMenuView.view.frame = rect
Messaging.messaging().delegate = self
// Siren.shared.wail()
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
// Do your task here
let dic = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary
let dic2 = dic?.value(forKey: "aps") as? NSDictionary
let alert = dic2?.value(forKey: "alert") as? NSDictionary
let category = dic2?.value(forKey: "title") as? String
// We can add one more key name 'click_action' in payload while sending push notification and check category for indentifying the push notification type. 'category' is one of the seven built in key of payload for identifying type of notification and take actions accordingly
if category == "News Added"
{
/// Set the flag true for is app open from Notification and on root view controller check the flag condition to take action accordingly
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
else if category == "1-2-1 notification"
{
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
}
return true
}
对于终止状态或终止状态:
在AppDelegate.swift文件
中定义新的属性
var isFromNotification = false
在 AppDelegate.swift 中进行以下更改并保持其余代码不变。
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
isFromNotification = true
//other required code
}
转到您的 Homepage.swift 文件
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated).
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if appDelegate.isFromNotification {
appDelegate.isFromNotification = false
//Push to your notification controler without animation
}
}
更新:背景和前景状态
以上答案仅适用于 @Abu Ul Hassan
评论中提到的 Kill 状态
现在,让我们了解背景或前景状态的流程。
userNotificationCenter(_:didReceive:withCompletionHandler:) 当用户在后台或前台模式下点击通知时调用方法。
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//other required code
//Get current navigation controller and redirect into notification screen
completionHandler()
}
How to grab current UIViewController or current UINavigationController
这里有两种情况要处理,一种是application
活着的时候,一种是不活着的时候。
当应用程序处于活动状态时,您将在 UserNotificationCenterDelegate
的 didReceiveNotificationResponse
函数中收到回调。您可以进行相应的处理。
启动应用程序时,您必须使用 AppDelegate
中的 didFinishLaunchingWithOptions
函数获得的 UIApplication.LaunchOptionsKey.remoteNotification
键
我在 swift 4.2
工作,从 FireBase
收到推送通知。当我点击 Notification
时,它会转到主页。但是我想去 Notification
页面。
这是Swift4.2
、Xcode 9.3
、iOS 12.1
。过去,我尝试过但没有同时使用 Foreground 和 InActive 应用程序
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
UINavigationBar.appearance().barTintColor = UIColor(red: 0/255.0, green: 85/255.0, blue: 127/255.0, alpha: 1)
UINavigationBar.appearance().tintColor = UIColor.white
// UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,NSAttributedString.Key.font: UIFont(name: "Roboto-Medium", size: 16)!]
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -60), for:UIBarMetrics.default)
UINavigationBar.appearance().isTranslucent = false
UIApplication.shared.statusBarStyle = .lightContent
IQKeyboardManager .shared().isEnabled = true
IQKeyboardManager .shared().shouldResignOnTouchOutside = true
IQKeyboardManager .shared().isEnableAutoToolbar = false
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {
// If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions
let aps = notification["aps"] as! [String: AnyObject]
UIApplication.shared.applicationIconBadgeNumber = 0
}
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
let mainview = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let nav = UINavigationController.init(rootViewController: mainview)
SideMenu = LGSideMenuController.init(rootViewController: nav)
SideMenuView = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "SideMenuViewController") as! SideMenuViewController
SideMenu.rightViewStatusBarVisibleOptions = .onAll
let rect = SideMenuView.view.frame;
SideMenuView.view.frame = rect
Messaging.messaging().delegate = self
// Siren.shared.wail()
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
// Do your task here
let dic = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary
let dic2 = dic?.value(forKey: "aps") as? NSDictionary
let alert = dic2?.value(forKey: "alert") as? NSDictionary
let category = dic2?.value(forKey: "title") as? String
// We can add one more key name 'click_action' in payload while sending push notification and check category for indentifying the push notification type. 'category' is one of the seven built in key of payload for identifying type of notification and take actions accordingly
if category == "News Added"
{
/// Set the flag true for is app open from Notification and on root view controller check the flag condition to take action accordingly
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
else if category == "1-2-1 notification"
{
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
}
return true
}
对于终止状态或终止状态:
在AppDelegate.swift文件
中定义新的属性var isFromNotification = false
在 AppDelegate.swift 中进行以下更改并保持其余代码不变。
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
isFromNotification = true
//other required code
}
转到您的 Homepage.swift 文件
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated).
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if appDelegate.isFromNotification {
appDelegate.isFromNotification = false
//Push to your notification controler without animation
}
}
更新:背景和前景状态
以上答案仅适用于 @Abu Ul Hassan
评论中提到的 Kill 状态现在,让我们了解背景或前景状态的流程。
userNotificationCenter(_:didReceive:withCompletionHandler:) 当用户在后台或前台模式下点击通知时调用方法。
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//other required code
//Get current navigation controller and redirect into notification screen
completionHandler()
}
How to grab current UIViewController or current UINavigationController
这里有两种情况要处理,一种是application
活着的时候,一种是不活着的时候。
当应用程序处于活动状态时,您将在 UserNotificationCenterDelegate
的 didReceiveNotificationResponse
函数中收到回调。您可以进行相应的处理。
启动应用程序时,您必须使用 AppDelegate
didFinishLaunchingWithOptions
函数获得的 UIApplication.LaunchOptionsKey.remoteNotification
键