My app has 2 types of initial state.
My app working fine when switching view from Appdelegate like that
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let userDataExist = CommonUserFunction.isUserDataExist() as Bool
if userDataExist == true {
let homeViewController = self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "HomeView") as? HomeViewController
let navigationController = UINavigationController()
navigationController.viewControllers = [homeViewController!]
self.window!.rootViewController = navigationController
}
else{
let loginController = self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "LoginView") as? LoginController
let navigationController = UINavigationController()
navigationController.viewControllers = [loginController!]
self.window!.rootViewController = navigationController
}
self.window?.makeKeyAndVisible()
return true
}
I am facing problem when i have to handle push notification. I received push notification in iOS 10 in these methods
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
print("Handle push from foreground")
// custom code to handle push while app is in the foreground
print(notification.request.content.userInfo)
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// custom code to handle push while app is in the foreground
print(response.notification.request.content.userInfo)
}
When i tapped notification from notification tray these two methods are fired whereas app is foreground or background. After tapping the notification i must show a details page. I tried to set the details page like that which i did before in didFinishLaunchingWithOptions method
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let pushResponse = response.notification.request.content.userInfo as NSDictionary
let rtype = pushResponse.object(forKey: "rtype") as? String
let rid = pushResponse.object(forKey: "rid") as? String
if rtype != nil {
if rtype == "5" {
if rid != nil {
let noticeDetailsViewController = self.storyboard?.instantiateViewController(withIdentifier: "NoticeDetailsView") as? NoticeDetailsController
noticeDetailsViewController!.id = rtype!
noticeDetailsViewController?.fromPush = true
let navigationController = UINavigationController()
navigationController.viewControllers = [noticeDetailsViewController!]
self.window!.rootViewController = navigationController
}
}
}
}
Every time i do that app crashes. How to overcome this. Please help. Thanks in advance.
Finally solved this using Observer design pattern.
When app is in Background & tapped the the notification in notification tray then post the notification from here like that
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let pushResponse = response.notification.request.content.userInfo as NSDictionary
let rtype = pushResponse.object(forKey: "rtype") as? String
let rid = pushResponse.object(forKey: "rid") as? String
if rtype != nil {
if rtype == "5" {
if rid != nil {
NotificationCenter.default.post(name: Notification.Name(rawValue: "getPush"), object: pushResponse)
}
}
}
}
To receive this notification init below code to your viewController
NotificationCenter.default.addObserver(self, selector: #selector(self.getPushResponse), name: NSNotification.Name(rawValue: "getPush"), object: nil)
Get response from the below code
func getPushResponse(_ notification: Notification){
if let info = notification.object as? NSDictionary {
let rid = info.object(forKey: "rid") as? String
let noticeDetailsViewController = self.storyboard?.instantiateViewController(withIdentifier: "NoticeDetailsView") as? NoticeDetailsController
noticeDetailsViewController?.id = rid!
noticeDetailsViewController?.fromPush = true
self.navigationController?.pushViewController(noticeDetailsViewController!, animated: true)
}
}
Don't forget to Remove Observer from the viewController like that
deinit {
NotificationCenter.default.removeObserver(self)
}
If app has no instance in background & tapped the notification in tray then how to show the notification which has no instance. This can be handle like that in AppDelegate
let prefs: UserDefaults = UserDefaults.standard
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
prefs.set(remoteNotification as! [AnyHashable: Any], forKey: "startUpPush")
prefs.synchronize()
}
Check your initial viewController is this key exist or not like that
let prefs:UserDefaults = UserDefaults.standard
if prefs.value(forKey: "startUpPush") != nil {
let pushResponse = prefs.object(forKey: "startUpPush") as! NSDictionary
NotificationCenter.default.post(name: Notification.Name(rawValue: "getPush"), object: pushResponse)
}
Don't forget to remove this key after showing the detailsController like that
if fromPush == true {
let prefs: UserDefaults = UserDefaults.standard
if prefs.value(forKey: "startUpPush") != nil {
prefs.removeObject(forKey: "startUpPush")
prefs.synchronize()
}
}