Wie kann ich in Swift eine Funktion mit einem Completion-Handler erstellen?

116

Ich war nur neugierig, wie ich das angehen würde. Wenn ich eine Funktion hätte und wollte, dass etwas passiert, wenn sie vollständig ausgeführt wurde, wie würde ich dies der Funktion hinzufügen? Vielen Dank

traw1233
quelle
2
Es gibt ein erstaunliches Video auf Youtube: google.com/…
Bright Future

Antworten:

174

Angenommen, Sie haben eine Download-Funktion zum Herunterladen einer Datei aus dem Netzwerk und möchten benachrichtigt werden, wenn die Download-Aufgabe abgeschlossen ist.

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
    }
})

Ich hoffe es hilft.

tounaobun
quelle
2
Das würde großartig funktionieren, aber mehr aus Neugier fragte ich mich, ob Sie irgendwie einen Completion-Handler in Ihre Funktion schreiben könnten.
Traw1233
1
Hallo Floks, ich möchte diesen CompletionHandler von einer anderen Funktion aus aufrufen. Wie kann man das erreichen?
Himanshu Jamnani
irgendein Beispiel für Ziel c
Xcodian Solangi
Wenn ich es von einer anderen Klasse aufrufe, sät es keinen Erfolgsparameter für den Abschluss-Handler.
Chandni
84

Ich hatte Probleme, die Antworten zu verstehen, daher gehe ich davon aus, dass jeder andere Anfänger wie ich das gleiche Problem haben könnte wie ich.

Meine Lösung entspricht der Top-Antwort, ist aber hoffentlich etwas klarer und verständlicher für Anfänger oder Leute, die nur Probleme mit dem Verständnis im Allgemeinen haben.

So erstellen Sie eine Funktion mit einem Completion-Handler

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

     print("Doing something!")

     finished()

}

um die Funktion zu nutzen

     override func viewDidLoad() {

          yourFunctionName {

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

    }

Ihre Ausgabe wird sein

Etwas machen

Tada !!!

Hoffe das hilft!

Cyril
quelle
80

Einfaches Swift 4.0-Beispiel:

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)
}

Wie man es benutzt:

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")
    }
})
Bobby
quelle
12

Zu diesem Zweck können wir Verschlüsse verwenden. Versuche Folgendes

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

Irgendwann können wir diese Funktion wie unten angegeben aufrufen.

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

Weitere Informationen zu Verschlüssen finden Sie unter folgendem Link .

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

arango_86
quelle
5

Swift 5.0 +, einfach und kurz

Beispiel:

Stil 1

    func methodName(completionBlock: () -> Void)  {

          print("block_Completion")
          completionBlock()
    }

Stil 2

    func methodName(completionBlock: () -> ())  {

        print("block_Completion")
        completionBlock()
    }

Verwenden:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        methodName {

            print("Doing something after Block_Completion!!")
        }
    }

Ausgabe

block_Completion

Nach Block_Completion etwas tun !!

Lakhdeep Singh
quelle
0

Ich bin ein wenig verwirrt über maßgeschneiderte Fertigstellungshandler. In Ihrem Beispiel:

Angenommen, Sie haben eine Download-Funktion zum Herunterladen einer Datei aus dem Netzwerk und möchten benachrichtigt werden, wenn die Download-Aufgabe abgeschlossen ist.

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)
}

Ihre // download code wird weiterhin asynchron ausgeführt. Warum geht der Code nicht direkt zu Ihnen let flag = trueund completion Handler(success: flag)ohne darauf zu warten, dass Ihr Download-Code fertig ist?

Schweres Atmen
quelle
Irgendwann muss etwas sitzen und warten, bis der Code ausgeführt wird. Es ist kein riesiger Turm asynchroner Elefanten ganz unten. "Asynchron ausgeführt" bedeutet, dass zwei Threads vorhanden sind. Einer von ihnen sitzt und wartet auf die Aufgabe, der andere macht weiter und tut es nicht. Der Completion-Handler wird am Ende des Threads, der die Arbeit ausführt, aufgerufen oder soll zumindest aufgerufen werden.
Crowman
0

Zusätzlich zu oben: Der hintere Verschluss kann verwendet werden.

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

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