web-dev-qa-db-fra.com

Méthode de délégué d'application simple pour afficher un UIAlertController (dans Swift)

Dans obj-C lorsqu'une autre application iOS (pièce jointe au courrier, lien Web) a été exploitée avec un fichier ou un lien associé à mon application. J'attraperais alors ceci sur openURL ou didFinishLaunchingWithOptions et montrerais un UIAlertView pour confirmer que l'utilisateur veut importer les données. Maintenant que UIAlertView est déprécié, j'essaie de faire la même chose mais je ne suis pas vraiment sûr de la meilleure façon de le faire?

J'ai du mal à afficher une alerte simple lorsque mon application reçoit des données d'une autre application. Ce code fonctionnait bien dans Objective-C avec un 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;
}

Mais quand j'essaie de passer à UIAlertViewController et Swift je n'arrive pas à trouver un moyen simple d'afficher le 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
}

Je reçois une erreur de temps de compilation que AppDelegate n'a pas de membre nommé presentViewController

J'ai vu quelques méthodes compliquées pour obtenir le AppDelegate pour afficher un UIAlertViewController sur StackOverflow mais j'espérais qu'il y avait quelque chose d'un peu plus simple.

Tout ce que je dois vraiment faire est de montrer à l'utilisateur un message rapide indiquant qu'il a obtenu des données et de lui faire décider ce qu'il veut en faire. Une fois terminé, mon application continuera à s'ouvrir et à apparaître au premier plan (code similaire dans didFinishLaunchingWithOptions pour un démarrage à froid) avec les nouvelles données ajoutées ou non en fonction de la sélection d'alerte.

Je pourrais signaler une variable globale que j'archive dans tous mes viewWillAppear func mais ce serait beaucoup de duplication puisque j'ai plus de 30 vues.

Faites-moi savoir si vous avez des idées.

Merci

Greg

38
Greg Robertson

Essayez d'utiliser

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

Tout ce dont vous avez besoin est un objet viewController pour présenter le AlertController.

Dans Swift 4:

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

Utilisez ce code pour lancer alertCV depuis 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)
    })

J'espère que cela t'aides!

20
Aditya Gaonkar

La meilleure façon que j'ai trouvée est la suivante:

        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
        }

J'ai ajouté un minuteur pour que l'UIAlertController soit fermé car il ne contient aucun bouton.

Merci à: https://stackoverflow.com/a/33128884/6144027 Réponse brillante sur la façon de présenter un UIAlertController d'AppDelegate.

2
Marie Amida

De l'intérieur du délégué de l'application.

window.rootViweController.presentViewController...

1
Daniel T.

La réponse acceptée en Swift 3 au cas où cela aiderait quelqu'un:

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