As I am very new to push notifications I have looked at several tutorials that outline the best way to handle remote push notifications when app is terminated and it seems that I still have an issue in my app. I am calling didFinishLaunchingWithOptions when push notification is tapped but for some reason the function is skipped over and does not execute the code to open the proper view controller.
Here is the code in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
//UserNotification
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
// Enable or disable features based on authorization.
if granted {
UIApplication.shared.registerForRemoteNotifications()
if GlobalService.sharedInstance().g_userDeviceToken == nil {
// GlobalService.sharedInstance().g_userDeviceToken = ""
}
} else {
print("Don't Allow")
}
if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: AnyObject] {
self.getUserChatRooms()
let aps = notification["aps"] as! [String: AnyObject]
let mainNC = self.window?.rootViewController as! UINavigationController
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let mainVC = storyboard.instantiateViewController(withIdentifier: String(describing: MainViewController.self)) as! MainViewController
GlobalService.sharedInstance().g_homeVC = mainVC
mainVC.didReceiveChat(aps)
mainNC.pushViewController(mainVC, animated: false)
}
...
//SVProgressHUD
SVProgressHUD.setDefaultStyle(.dark)
//Check UserObj
GlobalService.sharedInstance().g_appDelegate = self
if let userObj = GlobalService.sharedInstance().loadUserObj() {
GlobalService.sharedInstance().g_userMe = userObj
startApplication(animated: false)
...
return true
}
then this is the function that is called in MainVC:
func didReceiveChat (_ notificationDictionary: [String: AnyObject]){
let allChats = GlobalService.sharedInstance().g_aryChatRooms
if let noti_id = notificationDictionary["noti_id"] as? String{
let pushID = Int(noti_id)
if pushID != nil {
for chat in allChats {
if chat.chat_room_id! == pushID! {
chtRoom = chat
NotificationCenter.default.post(name: Notification.Name(rawValue: Constants.Notifications.GET_MSG), object: self)
break
}
}
}
}
}
and then in my viewDidLoad method I add the observer:
NotificationCenter.default.addObserver(self,selector: #selector(MainViewController.addChatScn(_:_:)), name: NSNotification.Name(rawValue: Constants.Notifications.GET_MSG), object: nil)
finally I call the method to addChatScn:
@objc func addChatScn(_ chatObj: ChatRoomObj, _ msgName: String) {
let popvc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChatContainerViewController") as! ChatContainerViewController
iconContainer.isHidden = true
add_Msg_Btn.isHidden = true
popvc.vcA = self
popvc.m_selectedChatRoom = chatObj
popvc.msgName = msgName
self.addChildViewController(popvc)
popvc.view.center = self.view.center
popvc.view.bounds.size = CGSize(width: 337, height: 503)
self.view.addSubview(popvc.view)
popvc.didMove(toParentViewController: self)
}
In your GlobalService.sharedInstance, Add a boolean value called 'readyToReceivePush'. In your MainVC in your viewDidLoad, set the 'GlobalService.sharedInstance.readyToReceivePush' to true. Set it to false if the app goes into the background, and true if it comes back to foreground.
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
GlobalService.sharedInstance.readyToReceivePush = false
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
GlobalService.sharedInstance.readyToReceivePush = true
}
Once you have that set up, if the user swipes on a notification the 'didReceiveRemoteNotification' will be called. In that method, if GlobalService.sharedInstance.readyToReceivePush == false, save the userInfo to GlobalService.sharedInstance.savedPushInfo.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if GlobalService.sharedInstance.readyToReceivePush == false {
GlobalService.sharedInstance.savedPushInfo = userInfo
} else {
// Handle notification while the user is in the foreground
}
}
Once you've done that, in MainVC check if GlobalService.sharedInstance.savedPushInfo != nil. If it is != nil, call your 'didReceiveChat' function or whatever you do to handle the notification's userInfo data.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.