Simple App Delegate method to show an UIAlertController (in Swift)

风流意气都作罢 提交于 2019-11-27 11:30:33

问题


In obj-C when another iOS app (mail attachment, web link) was tapped with a file or link associated with my app. I would then catch this on openURL or didFinishLaunchingWithOptions and show a UIAlertView to confirm the user wants to import the data. Now that UIAlertView is depreciated I am trying to do the same thing but not really sure about the best way to do this?

I am having trouble showing a simple alert when my App receives data from another app. This code worked fine in Objective-C with a UIAlertView:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    if (url)
    {
        self.URLString = [url absoluteString];
        NSString *message = @"Received a data exchange request. Would you like to import it?";
        importAlert = [[UIAlertView alloc] initWithTitle:@"Data Received" message:message delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
        [importAlert show];
    }

    return YES;
}

But when I try and switch to UIAlertViewController and Swift I can't seem to find a simple way to display the message:

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
    let URLString: String = url.absoluteString!
    let message: String = "Received data. Would you like to import it?"

    var importAlert: UIAlertController = UIAlertController(title: "Data Received", message: message, preferredStyle: UIAlertControllerStyle.Alert)
    importAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
    importAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler:
    { action in
        switch action.style {
        case .Default:
            println("default")  
        case .Cancel:
            println("cancel")   
        case .Destructive:
            println("destructive")
        }
    }))

    self.presentViewController(importAlert, animated: true, completion: nil)
    return true
}

I get a compile time error that AppDelegate does not have a member named presentViewController

I have seen some convoluted methods to get the AppDelegate to display an UIAlertViewController on StackOverflow but I was hoping there was something a little simpler.

All I really need to do is show the user a quick message that they got some data and have them decide what they want to do with it. Once were done my app will continue to open and come to foreground (similar code in didFinishLaunchingWithOptions for cold start) with either the new data added or not based on the alert selection.

I could flag a global variable that I check in all my viewWillAppear func but this would be a lot of duplication since I have 30+ views.

Let me know if you have any ideas.

Thanks

Greg


回答1:


Try using

self.window?.rootViewController?.presentViewController(importAlert, animated: true, completion: nil)

All you need is a viewController object to present the AlertController from.

In Swift 4:

self.window?.rootViewController?.present(importAlert, animated: true, completion: nil)



回答2:


Use this code to launch alertCV from appdelegate

    dispatch_async(dispatch_get_main_queue(), {
          let importantAlert: UIAlertController = UIAlertController(title: "Action Sheet", message: "Hello I was presented from appdelegate ;)", preferredStyle: .ActionSheet)
        self.window?.rootViewController?.presentViewController(importantAlert, animated: true, completion: nil)
    })

Hope this helps!




回答3:


The best way I've found is the following:

        let importantAlert: UIAlertController = UIAlertController(title: "Action Sheet", message: "Hello I was presented from appdelegate ;)", preferredStyle: .ActionSheet) //.Alert .ActionSheet
        var hostVC = UIApplication.sharedApplication().keyWindow?.rootViewController
        while let next = hostVC?.presentedViewController {
            hostVC = next
        }
        hostVC?.presentViewController(importantAlert, animated: true, completion: nil)


        let delay = 1.5 * Double(NSEC_PER_SEC)
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
        dispatch_after(time, dispatch_get_main_queue()) {

            importantAlert.dismissViewControllerAnimated(true, completion: nil)

            return
        }

I've added a timer so the UIAlertController is dismissed since it doesn't have any buttons in it.

Thanks to: https://stackoverflow.com/a/33128884/6144027 Brilliant answer on how to present a UIAlertController from AppDelegate.




回答4:


From inside the app delegate.

window.rootViweController.presentViewController...




回答5:


The accepted answer in Swift 3 in case it helps anyone:

self.window?.rootViewController?.present(importAlert, animated: true, completion: nil)


来源:https://stackoverflow.com/questions/26627511/simple-app-delegate-method-to-show-an-uialertcontroller-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!