2016-07-10 12 views
1

Also verwende ich Fabric Plugin/Twitter-Kit, um Twitter API in meiner Anwendung zu verwenden. Ich möchte die Bild-URL des Profilbilds eines Prominenten erhalten. Hier ist mein Code unten.Wie gibt man einen Wert von einem Closure in Swift zurück?

Ich weiß nicht, wie man Wert zurückgibt, weil die Methode beendet wird, bevor die Schließung vollständig ausgeführt wird. Ich bin neu zu schnell, Jede Hilfe wird geschätzt.

Ich möchte diese Methode in CellForRowIndexPath in der Tabellenansicht verwenden, um Bild von imageURl herunterzuladen.

+0

Siehe [Wie kann ein Wert aus einem Lückenschluss in Swift zurückgegeben werden?] (Http://stackoverflow.com/questions/37798352/how-to-return-a-value-from-a-void-closure-in -schnell). – OOPer

+0

http://stackoverflow.com/questions/38160959/void-inside-of-return-function/38161092#38161092 – penatheboss

Antwort

4

Sie sind richtig, sendTwitterRequest wird zurückgegeben, nachdem Ihre Funktion bereits zurückgegeben wurde, also gibt es keine Möglichkeit für die äußere Funktion, ein imageURL zurückzugeben.

Stattdessen in der Schließung, nehmen Sie den Rückgabewert, den Sie wollen in der Zelle und speichern Sie es irgendwo (in einer Member-Variable) und lassen Sie die TableView selbst aktualisieren (z. B. mit tableView.reloadData()).

Dies wird dazu führen, dass es die Zelle wieder (cellForRow ...) bekommen. Ändern Sie die Implementierung, um die Mitgliedsvariable zu verwenden, in der Sie den Wert aus dem Aufruf gespeichert haben.

0

Sie müssen von einem @escaping-Verschluss zurückkehren. die

func getImageURL(celebrity: String, completion:(String)->()) { 

     // your code 
     completion(imgURL) 
} 

zu

func getImageURL(celebrity: String) -> String { 

} 

Funktion Ändern können Sie es unter

getImageURL(celebrity: String) { (imgURL) in 

     self.imgURL = imgURL // Using self as the closure is running in background 
} 

Hier ist ein Beispiel, wie angegeben verwenden, wie ich mehrere Methoden mit Verschlüssen für die Fertigstellung schreiben.

class ServiceManager: NSObject { 

// Static Instance variable for Singleton 
static var sharedSessionManager = ServiceManager() 

// Function to execute GET request and pass data from escaping closure 
func executeGetRequest(with urlString: String, completion: @escaping (Data?) ->()) { 

    let url = URL.init(string: urlString) 
    let urlRequest = URLRequest(url: url!) 

    URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in 
     // Log errors (if any) 
     if error != nil { 
      print(error.debugDescription) 
     } else { 
      // Passing the data from closure to the calling method 
      completion(data) 
     } 
    }.resume() // Starting the dataTask 
} 

// Function to perform a task - Calls executeGetRequest(with urlString:) and receives data from the closure. 
func downloadMovies(from urlString: String, completion: @escaping ([Movie]) ->()) { 
    // Calling executeGetRequest(with:) 
    executeGetRequest(with: urlString) { (data) in // Data received from closure 
     do { 
      // JSON parsing 
      let responseDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] 
      if let results = responseDict!["results"] as? [[String:Any]] { 
       var movies = [Movie]() 
       for obj in results { 
        let movie = Movie(movieDict: obj) 
        movies.append(movie) 
       } 
       // Passing parsed JSON data from closure to the calling method. 
       completion(movies) 
      } 
     } catch { 
      print("ERROR: could not retrieve response") 
     } 
    } 
    } 
} 

Unten ist das Beispiel, wie ich es verwende, um Werte zu übergeben.

ServiceManager.sharedSessionManager.downloadMovies(from: urlBase) { (movies : [Movie]) in // Object received from closure 
     self.movies = movies 
     DispatchQueue.main.async { 
      // Updating UI on main queue 
      self.movieCollectionView.reloadData() 
     } 
} 

Ich hoffe, das hilft jedem auf der Suche nach der gleichen Lösung.