在 Swift 4 中
如果你需要实现上述情况你必须处理2个情况
- 当您的应用程序处于后台/前台状态时(如果推送
通知不会静音)
- 当您的应用处于非活动状态时
如果有超过 1 种通知类型,我在这里使用类别(推送通知的有效负载中的内置参数来识别通知类型)。如果您只有一种类型的通知,则无需检查类别。
那么对于第一种情况的处理,AppDelegate File中的代码如下
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let title = response.notification.request.content.title
//Method- 1 -- By using NotificationCenter if you want to take action on push notification on particular View Controllers
switch response.notification.request.content.categoryIdentifier
{
case "Second":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SecondTypeNotification"), object: title, userInfo: userInfo)
break
case "Third":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ThirdTypeNotification"), object: title, userInfo: userInfo)
break
default:
break
}
///Method -2 --- Check the view controller at the top and then push to the required View Controller
if let currentVC = UIApplication.topViewController() {
//the type of currentVC is MyViewController inside the if statement, use it as you want to
if response.notification.request.content.categoryIdentifier == "Second"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
else if response.notification.request.content.categoryIdentifier == "Third"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
}
completionHandler() }
对于方法 1-
之后,您必须在默认视图控制器中添加观察者,如下所示在 viewDidLoad
NotificationCenter.default.addObserver(self,selector: #selector(SecondTypeNotification),
name: NSNotification.Name(rawValue: "SecondTypeNotification"),
object: nil)
NotificationCenter.default.addObserver(self,selector:#selector(ThirdTypeNotification),
name: NSNotification.Name(rawValue: "ThirdTypeNotification"),
object: nil)
对于方法 1-
并且还需要添加两个Notification Observer函数,用于添加与Observer中使用的同名要执行的动作。
// Action to be taken if push notification is opened and observer is called while app is in background or active
@objc func SecondTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
@objc func ThirdTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
因此,每当应用程序处于前台或后台时打开通知时,上述内容都会执行并根据有效负载中的类别移动到相应的视图控制器。
现在是第二种情况
我们知道,当应用处于非活动状态时,打开推送通知时将调用的第一个函数是
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
所以我们必须在这个函数中检查应用程序是通过打开推送通知还是通过单击应用程序图标来启动的。为此,我们提供了一项规定。添加所需代码后,函数如下所示。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
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)
}
// Register the notification categories.
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
/// Check if the app is launched by opening push notification
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: "category") 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
// Method - 1
if category == "Second"
{
/// 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 == "Third"
{
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
// Method 2: Check top view controller and push to required view controller
if let currentVC = UIApplication.topViewController() {
if category == "Second"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
else if category == "Third"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
}
}
return true
}
For Method 1-
After this, check these flags value in the default view controller in viewdidLoad as follows
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationSecond) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationThird) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
这将实现在打开推送通知时打开特定视图控制器的目标。
您可以浏览此博客-How to open a particular View Controller when the user taps on the push notification received? 以供参考。