Open a ViewController from remote notification
Asked Answered
B

1

10

I would like to open a ViewController when my app catches a remote notification.

When I receive the notification I want to 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.

Blain answered 23/8, 2016 at 23:16 Comment(1)
Search for "instantiate view controller from storyboard "Aten
A
11

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

Acth answered 24/8, 2016 at 0:16 Comment(3)
Thanks for your example and the great code you shared. I found an almost similar solution, I edited my question to show you.Blain
Great glad you figured it out - could you accept the answer as well?Acth
But doesn't this create a new view controller instead of grabbing the existing instance?Phobe

© 2022 - 2024 — McMap. All rights reserved.