web-dev-qa-db-fra.com

Comment créer une fonction avec un gestionnaire de complétion dans Swift?

J'étais juste curieux de savoir comment j'aborderais cela. Si j'avais une fonction et que je voulais que quelque chose se produise lorsqu'elle était complètement exécutée, comment pourrais-je l'ajouter à la fonction? Merci

100
traw1233

Supposons que vous ayez une fonction de téléchargement pour télécharger un fichier depuis le réseau et que vous souhaitiez être averti lorsque la tâche de téléchargement est terminée.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

// How to use it.

downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in

    // When download completes,control flow goes here.
    if success {
        // download success
    } else {
        // download fail
    }
})

J'espère que ça aide. : -]

148
tounaobun

Exemple simple Swift 4.0:

func method(arg: Bool, completion: (Bool) -> ()) {
    print("First line of code executed")
    // do stuff here to determine what you want to "send back".
    // we are just sending the Boolean value that was sent in "back"
    completion(arg)
}

Comment l'utiliser:

method(arg: true, completion: { (success) -> Void in
    print("Second line of code executed")
    if success { // this will be equal to whatever value is set in this method call
          print("true")
    } else {
         print("false")
    }
})
70
Bobby

J'ai eu du mal à comprendre les réponses, alors je suppose qu'un autre débutant comme moi pourrait avoir le même problème que moi.

Ma solution fait la même chose que la réponse principale mais, espérons-le, un peu plus claire et facile à comprendre pour les débutants ou les personnes ayant simplement du mal à comprendre en général.

Pour créer une fonction avec un gestionnaire d'achèvement

func yourFunctionName(finished: () -> Void) {

     print("Doing something!")

     finished()

}

utiliser la fonction

     override func viewDidLoad() {

          yourFunctionName {

          //do something here after running your function
           print("Tada!!!!")
          }

    }

Votre sortie sera

Doing something
Tada!!!

J'espère que cela t'aides!

64
Cyril Ivar Garcia

Nous pouvons utiliser des fermetures à cette fin. Essayez ce qui suit

func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
      //some code here
      completionClosure(indexes: list)
}

À un moment donné, nous pouvons appeler cette fonction comme indiqué ci-dessous.

healthIndexManager.loadHealthCareList { (indexes) -> () in
            print(indexes)
}

Veuillez vous référer au lien suivant pour plus d'informations concernant les fermetures .

https://developer.Apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

11
arango_86

Je suis un peu confus au sujet des gestionnaires d'achèvement sur mesure. Dans votre exemple:

Supposons que vous ayez une fonction de téléchargement pour télécharger un fichier depuis le réseau et que vous souhaitiez être averti lorsque la tâche de téléchargement est terminée.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

Votre // download code sera toujours exécuté de manière asynchrone. Pourquoi le code ne va-t-il pas directement à votre let flag = true et completion Handler(success: flag) sans attendre que votre code de téléchargement soit terminé?

1
Heavy Breathing

En plus de ce qui précède: Fermeture arrière peut être utilisé.

downloadFileFromURL(NSURL(string: "url_str")!)  { (success) -> Void in

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
0
Shrawan