Reputation: 277
I have an UITabBarController
which presents in one tab a table of chats. If the user clicks on one row, a view controller will be displayed that presents the latest messages.
Now I am introducing Push notifications. The desired behavior would be to automatically go to the chat room if the user opens up the Push notification. Although there's plenty information available on how to handle these use cases, I do not succeed in implementing it.
Here's my code so far:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if (!isUserLoggedIn()) {
// show login vc
} else {
let protectedController = mainStoryboard.instantiateViewController(withIdentifier: "TabBarController") as! UITabBarController
if let notificationPayload = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
if let chatId = notificationPayload["chatId"] as? String {
print(chatId)
// show chat VC
}
}
window!.rootViewController = protectedController
window!.makeKeyAndVisible()
}
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
// Enable or disable features based on authorization.
}
application.registerForRemoteNotifications()
return true
}
The print statement will never be called but that may be due to the fact that the application is completely closed before opening the notification.
Upvotes: 0
Views: 4100
Reputation: 491
When the user taps on a notification, callback method of the app delegate is:
application:didReceiveRemoteNotification:fetchCompletionHandler:
More information about notifications from Apple.
You should put your code inside this method.
Also you can create Router class (subclass of NSObject), which will show chat view controller and will be responsible for navigation between view controllers in application.
It's a good manner incapsulate this logic into separate class, not keeping it in the AppDelegate class.
Upvotes: 0
Reputation: 5766
didFinishLaunchingWithOptions
is not necessarily called, when you click on a notification, only if your app is not in the memory anymore
In your willFinishLaunchingWithOptions
function of your appDelegate, set up a delegate for the currentNotificationCenter
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
}
Make sure your AppDelegate
implements UNUserNotificationCenterDelegate
relevant for you could be this
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let chatID = userInfo["chatID"] as? String {
// here you can instantiate / select the viewController and present it
}
completionHandler()
}
Update to answer your follow-up question: How to add a UIViewController
to a UINavigationController
within your UITabbarController
In order to instantiate your ViewController and add it to your UITabbarController
:
let myViewController = MyViewController()
guard let tabbarController = self.window.rootViewController as? UITabbarController else {
// your rootViewController is no UITabbarController
return
}
guard let selectedNavigationController = tabbarController.selectedViewController as? UINavigationController else {
// the selected viewController in your tabbarController is no navigationController!
return
}
selectedNavigationController.pushViewController(myViewController, animated: true)
Upvotes: 1