How to present UIAlertView from appDelegate

I m trying to display a UIAlertView from the appDelegate in
didReceiveRemoteNotification
when the app receive a push notification.

I ve this error :

  • publishing on my facebook wall using new sdk
  • How to add a border to a circular image with mask
  • Replacing images in the bundle at run time
  • Why doesn't sin() return the correct value?
  • Xcode: Release app update for iPhone only?
  • How do I add a Navigation Bar to a UITableViewController in Interface Builder?
  •   Warning: Attempt to present <UIAlertController: 0x14c5494c0> on <UINavigationController:
      0x14c60ce00> whose view is not in the window hierarchy!
    

    here is my code :

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: NSDictionary) {
    
        var contentPush: NSDictionary = userInfo.objectForKey("aps") as NSDictionary
    
        var message = contentPush.objectForKey("alert") as String
    
    
    
        let alertController = UIAlertController(title: "Default Style", message: message, preferredStyle: .Alert)
    
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
                        // ...
        }
        alertController.addAction(cancelAction)
    
        let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
    
            let photoPushedVc = self.storyboard.instantiateViewControllerWithIdentifier("CommentTableViewController") as CommentTableViewController
    
            println("the fetched post is \(post)")
    
            photoPushedVc.post = post
    
            let activeVc = UIApplication.sharedApplication().keyWindow?.rootViewController
    
            activeVc?.presentViewController(photoPushedVc, animated: true, completion: nil)
       }
    
       alertController.addAction(OKAction)
    
       let activeVc = UIApplication.sharedApplication().keyWindow?.rootViewController
    
    
       activeVc?.presentViewController(alertController, animated: true, completion: nil)}
    

    7 Solutions Collect From Internet About “How to present UIAlertView from appDelegate”

    To generate AlertController Dialog Box from AppDelegate using Objective-C,

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Hello World!" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
    [alertController addAction:ok];
    

    Type 1

    UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    alertWindow.rootViewController = [[UIViewController alloc] init];
    alertWindow.windowLevel = UIWindowLevelAlert + 1;
    [alertWindow makeKeyAndVisible];
    [alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
    

    Type 2

    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }
    [topController presentViewController:alertController animated:YES completion:nil];
    

    Both are tested and working fine.

    Ok i finally got it, you need to find the active VC using this before trying to present your alertController :

       let navigationController = application.windows[0].rootViewController as UINavigationController
    
                    let activeViewCont = navigationController.visibleViewController
    
                    activeViewCont.presentViewController(alertController, animated: true, completion: nil)
    

    how i did it

    func showAlertAppDelegate(title : String,message : String,buttonTitle : String,window: UIWindow){
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.Default, handler: nil))
        window.rootViewController?.presentViewController(alert, animated: true, completion: nil)
    }
    

    Use Example

    self.showAlertAppDelegate("Alert",message: "Opened From AppDelegate",buttonTitle: "ok",window: self.window!);
    

    Download Example With Source Code

    If you need the same in Objective-c

    UIAlertController *alertvc = [UIAlertController alertControllerWithTitle:@"Alert Title..!!" message:@"Hey! Alert body come here." preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *actionOk = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    
    }];
    
    [alertvc addAction:actionOk];
    
    1. If you have navigation based app:

      UINavigationController *nvc = (UINavigationController *)[[application windows] objectAtIndex:0].rootViewController;
      UIViewController *vc = nvc.visibleViewController;
      [vc presentViewController:alertvc animated:YES completion:nil];
      
    2. If you have single view based app:

      UIViewController *vc = self.window.rootViewController;
      [vc presentViewController:alertvc animated:YES completion:nil];
      

    Here is mine Swift 3.0 example

    func showTopLevelAlert() {
        let alertController = UIAlertController (title: "title", message: "message.", preferredStyle: .alert)
    
        let firstAction = UIAlertAction(title: "First", style: .default, handler: nil)
        alertController.addAction(firstAction)
    
        let cancelAction = UIAlertAction(title: "Отмена", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
    
        let alertWindow = UIWindow(frame: UIScreen.main.bounds)
    
        alertWindow.rootViewController = UIViewController()
        alertWindow.windowLevel = UIWindowLevelAlert + 1;
        alertWindow.makeKeyAndVisible()
    
        alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)
    
    }
    

    Hope it helps to someone

    To show alert on top controller from app delegate

    var topController : UIViewController = (application.keyWindow?.rootViewController)!
    
        while ((topController.presentedViewController) != nil) {
            topController = topController.presentedViewController!
        }
    
        //showAlertInViewController func is in UIAlertController Extension
        UIAlertController.showAlertInViewController(topController, withMessage: messageString, title: titleString)
    

    Add extension in UIAlertController

        static func showAlertInViewController(viewController: UIViewController?, withMessage message: String, title: String) {
        let myAlert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    
        myAlert.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .Default, handler: { (action: UIAlertAction!) in
            print("Handle Ok logic here")
    
            // Let the alert simply dismiss for now
        }))
    
        viewController?.presentViewController(myAlert, animated: true, completion: nil)
    }
    

    I use an UIViewController extension to get the current visible view controller (see: How to get visible viewController from app delegate when using storyboard?).

    and then present the alert controller:

    let visibleVC = UIApplication.sharedApplication().keyWindow?.rootViewController?.visibleViewController
    visibleVC!.presentViewController(alertController, animated: true, completion: nil)