J'ai parcouru les questions de StackOverflow pour essayer de comprendre où je me trompe avec mon code, mais je n'arrive tout simplement pas à le faire! J'essaie de convertir mon Swift 1.2 en Swift 2.0) et je rencontre un problème avec ma classe qui télécharge des données JSON.
Je reçois continuellement l'erreur valeur de retour non vide inattendue dans la fonction void.
Voici le code, quelque peu tronqué, que j'utilise;
...
class func fetchMinionData() -> [Minion] {
var myURL = "http://myurl/test.json"
let dataURL = NSURL(string: myURL)
let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
let minionJSON = JSON(data!)
var minions = [Minion]()
for (_, minionDictionary) in minionJSON {
minions.append(Minion(minionDetails: minionDictionary))
}
return minions
//THIS IS WHERE THE ERROR OCCURS
}).resume()
}
...
J'ai peut-être oublié quelque chose de simple, mais je ne sais pas pourquoi ma fonction serait considérée comme nulle. Toute pensée serait immensément appréciée! Merci!
Vous avez un problème parce que votre ligne:
return minions
ne revient pas de votre fonction. Au lieu de cela, il retourne du gestionnaire d'achèvement dans dataTaskWithRequest
. Et cela ne devrait pas être le cas, car cette fermeture est une fonction vide.
Le problème que vous rencontrez provient du fait que dataTaskWithRequest
est une opération asynchrone. Ce qui signifie qu'il peut revenir plus tard après avoir exécuté votre fonction.
Donc, vous devez changer votre modèle de conception.
Une façon de faire serait la suivante:
static var minions:[Minion] = [] {
didSet {
NSNotificationCenter.defaultCenter().postNotificationName("minionsFetched", object: nil)
}
}
class func fetchMinionData() {
var myURL = "http://myurl/test.json"
let dataURL = NSURL(string: myURL)
let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
let minionJSON = JSON(data!)
var minions = [Minion]()
for (_, minionDictionary) in minionJSON {
minions.append(Minion(minionDetails: minionDictionary))
}
self.minions = minions
//THIS IS WHERE THE ERROR OCCURS
}).resume()
}
Ensuite, avant d'appeler votre fonction, vous devez vous enregistrer pour écouter NSNotification
avec le nom "minionsFetched". Et seulement après avoir reçu cette notification, vous devriez traiter les sbires comme s'ils avaient été récupérés.
J'ai corrigé le mien en créant un gestionnaire d'achèvement. Vous pouvez le faire au lieu d'utiliser des notifications:
class func fetchMinionData(completionHandler: (minions: [Minion]) -> Void) {
var myURL = "http://myurl/test.json"
let dataURL = NSURL(string: myURL)
let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
let minionJSON = JSON(data!)
var minions = [Minion]()
for (_, minionDictionary) in minionJSON {
minions.append(Minion(minionDetails: minionDictionary))
}
completionHandler(minions: minions)
//THIS IS WHERE YOUR PREVIOUS ERROR OCCURRED
}).resume()
}