Question or problem in the Swift programming language:
I try to open a particular ViewController when my app catch a remote notification.
Let me show my project’s architecture.
Here my storyboard :
When I receive a notification I want open a “SimplePostViewController”, so this is my appDelegate :
var window: UIWindow? var navigationVC: UINavigationController? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound] let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil) let storyboard = UIStoryboard(name: "Main", bundle: nil) self.navigationVC = storyboard.instantiateViewControllerWithIdentifier("LastestPostsNavigationController") as? UINavigationController application.registerUserNotificationSettings(pushNotificationSettings) application.registerForRemoteNotifications() return true } func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) { if let postId = userInfo["postId"] as? String { print(postId) let api = EVWordPressAPI(wordpressOauth2Settings: WordPress.wordpressOauth2Settings, site: WordPress.siteName) api.postById(postId) { post in if (post != nil) { self.navigationVC!.pushViewController(SimplePostViewController(), animated: true) } else { print("An error occurred") } } } }
I save my UINavigationViewController when the app is launch and simply try to push a new SimplePostViewController when I receive a notification. But nothing happen.
I placed breakpoints and seen that my pushViewController method was reached, but not the ViewWillAppear of my SimplePostViewController.
I also used the “whats new” view add perform my segue but nothing happen too.
Solution :
for child in (self.rootViewController?.childViewControllers)! { if child.restorationIdentifier == "LastestPostsNavigationController" { let lastestPostsTableViewController = (child.childViewControllers[0]) as! LastestPostsTableViewController let simplePostVC = (self.storyboard?.instantiateViewControllerWithIdentifier("PostViewController"))! as! PostViewController simplePostVC.post = post lastestPostsTableViewController.navigationController?.pushViewController(simplePostVC, animated: true) } }
I use :
child.childViewControllers[0]
because I’ve only one child in my example.
How to solve the problem:
I created a sample project with a local notification instead of a remote notification for ease of showing the functionality but it should be as simple as setting the root view controller of the window in the app delegate didreceiveremote notification.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Subscribe for notifications - assume the user chose yes for now application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)) return true } func applicationDidEnterBackground(application: UIApplication) { //Crete a local notification let notification = UILocalNotification() notification.alertBody = "This is a fake notification" notification.fireDate = NSDate(timeIntervalSinceNow: 2) UIApplication.sharedApplication().scheduleLocalNotification(notification) } func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) { let sb = UIStoryboard(name: "Main", bundle: nil) let otherVC = sb.instantiateViewControllerWithIdentifier("otherVC") as! OtherViewController window?.rootViewController = otherVC; } func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) { //Your code here }
`
You need to worry about managing your view hierarchy and sending anything to it that you need to send from the notification user data.
In my example, I create a local notification when you close the app that fires after a view seconds. If you then launch the app from the notification, it will open the “other view controller” which would be the “SimplePostViewController” in your case.
Also, be sure that you are registering for remote notifications in the didFinishLaunchWithOptions.
Github very simple sample : https://github.com/spt131/exampleNotificationResponse