Il existe un problème plus profond ici que vous essayez de renvoyer des données à partir d'une méthode qui s'exécute de manière asynchrone. Vous devez changer votre méthode de ne pas retourner quoi que ce soit, en soi, mais l'offre plutôt un gestionnaire d'achèvement par lequel vous pouvez de manière asynchrone passer de nouveau les données pertinentes:
class func downloadJSONFile(completionHandler:(AnyObject?) ->()) {
let requestURL: NSURL = NSURL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) { data, response, error in
// check for fundamental networking errors
guard error == nil && data != nil else {
print(error)
completionHandler(nil)
return
}
// check to see if status code found, and if so, that it's 200
guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else {
completionHandler(nil)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:[])
completionHandler(json)
} catch let parseError as NSError {
print("Error with Json: \(parseError)")
completionHandler(nil)
}
}
task.resume()
}
puis vous l'appelez, en utilisant le gestionnaire d'achèvement (ou utilisation la syntaxe de fermeture arrière, comme indiqué ci-dessous):
APIClass.downloadJSONFile() { json in
guard json != nil else {
print("there was some problem")
return
}
// now you can use `json` here
dispatch_async(dispatch_get_main_queue()) {
// and if you're doing any model or UI updates, dispatch that back to the main queue
}
}
// but do not use `json` here, as the above runs asynchronously
Notez que si vous vouliez fournir les informations d'erreur à la routine d'appel, vous pouvez changer pour revenir également les informations d'erreur, par exemple:
enum DownloadError : ErrorType {
case NetworkError(NSError?)
case NotHTTPResponse
case InvalidHTTPResponse(Int)
case JSONError(NSError)
}
class func downloadJSONFile(completionHandler:(AnyObject?, ErrorType?) ->()) {
let requestURL: NSURL = NSURL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) { data, response, error in
guard error == nil && data != nil else {
completionHandler(nil, DownloadError.NetworkError(error))
return
}
guard let httpResponse = response as? NSHTTPURLResponse else {
completionHandler(nil, DownloadError.NotHTTPResponse)
return
}
guard httpResponse.statusCode == 200 else {
completionHandler(nil, DownloadError.InvalidHTTPResponse(httpResponse.statusCode))
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:[])
completionHandler(json, nil)
} catch let parseError as NSError {
completionHandler(nil, DownloadError.JSONError(parseError))
}
}
task.resume()
}
Et, de toute évidence, l'appel changerait à prendre les deux paramètres:
APIClass.downloadJSONFile() { json, error in
guard json != nil && error == nil else {
print("there was some problem \(error)")
return
}
// and then it would be like before ...
}
Vous ne pas * retour * à partir d'un appel asynchrone. Exemple ici: http://stackoverflow.com/a/35358750/2227743 De plus, vous ne devriez pas forcer la réponse, il se peut qu'elle ne soit pas ici, donc vérifiez d'abord le paramètre d'erreur. – Moritz