Valor De Retorno No Nulo Inesperado En La Función Void (Swift 2.0)


He estado revisando las preguntas de StackOverflow tratando de averiguar en qué me estoy equivocando con mi código, ¡pero parece que no puedo! Estoy tratando de convertir mi proyecto Swift 1.2 a Swift 2.0, y estoy teniendo un problema con mi clase que descarga datos JSON.

Recibo continuamente el error Valor de retorno no nulo inesperado en la función void.

Aquí está el código, algo truncado, que estoy usando;

...

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

...

Tal vez estoy pasando por alto algo simple, pero no estoy seguro de por qué mi función sería considerada nula en absoluto. Cualquier pensamiento sería inmensamente apreciado! ¡Gracias!

Author: whyceewhite, 2015-08-20

2 answers

Tienes un problema porque tu línea:

return minions

No regresa de su función. En su lugar, regresa desde el controlador de finalización en dataTaskWithRequest. Y no debería hacerlo porque ese cierre es una función de vacío.

El problema que usted tiene resulta del hecho de que dataTaskWithRequest es una operación asíncrona. Lo que significa que puede volver más tarde después de ejecutar su función.

Por lo tanto, necesita cambiar su patrón de diseño.

Una forma de hacerlo sería el siguiente:

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

Entonces, antes de llamar a su función, debe registrarse para escuchar NSNotification con el nombre "minionsFetched". Y solo después de recibir esa notificación, debe procesar a los esbirros como si fueran recuperados.

 54
Author: Andriy Gordiychuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 23:09:30

Arreglé el mío creando un controlador de finalización. Puedes hacer esto en lugar de usar notificaciones:

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()
}
 20
Author: jaytrixz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-28 10:49:23