examples - swift functions
¿Cómo utilizar el cierre de HandHendelling con retorno en Swift? (4)
Como puede ver here , dataTaskWithRequest:completionHandler:
tiene un controlador de finalización sin valor de retorno esperado.
eso significa que la instancia de NSURLSession
no espera que ningún valor de usted continúe después de llamar a este método; con otras palabras: el cierre de finalización (o bloque, si lo desea) finaliza el procedimiento aquí.
no está claro por qué le gustaría enviar algo a la persona que llama a través del controlador de finalización .
Estoy intentando con nosotros una API REST que devuelve algunos datos json. Quiero encapsular el código que crea la solicitud HTTP y establece los encabezados en su propio método para poder llamarlo ingresando una cadena url y luego hacer que el método devuelva un objeto JSON.
En el siguiente fragmento de código, ya he creado el objeto de solicitud y establecido los encabezados, y llamo a esa variable "req". No he declarado ningún objeto llamado datos, respuesta o error. Tengo el siguiente código que imprime correctamente un objeto JSON
let sesh = NSURLSession.sharedSession()
let dataTask = sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error) in
var jsonError : NSError?
let jsonBlob = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableLeaves, error: &jsonError)
println(jsonBlob)
});
dataTask.resume()
Así que aquí está mi pregunta. ¿Cómo hago para que este bloque de FinalizaciónHandler pueda devolver el jsonBlob, que es de tipo "AnyObject!"? Si modifico ligeramente el código para que sea el siguiente:
let sesh = NSURLSession.sharedSession()
let dataTask = sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error) -> AnyObject! in
var jsonError : NSError?
let jsonBlob : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableLeaves, error: &jsonError)
return jsonBlob
});
dataTask.resume()
entonces el programa no se compilará como la llamada a dataTaskWithRequest: completedHandler muestra una advertencia del compilador que dice:
Could not find an overload for ''dataTaskWithRequest'' that accepts the supplied arguments
No entiendo esto Estoy usando la sintaxis correcta para devolver los cierres, como se muestra en esta página de Swift Docs:
El controlador de finalización no puede devolver nada porque el cierre que debe proporcionar debe ser del tipo de devolución Void y no de AnyObject !.
func dataTaskWithRequest(_ request: NSURLRequest!,
completionHandler completionHandler: ((NSData!,
NSURLResponse!,
NSError!) -> Void)!) -> NSURLSessionDataTask!
Me encontré con un problema similar cuando intentaba actualizar la información en una base de datos central basada en el contenido que estaba sacando de CloudKit. Los patrones para extraer datos de CK tienen todos estos controladores de finalización asíncronos que no permiten ningún valor de retorno.
Como quería poder reutilizar código similar en diferentes contextos, separé las llamadas de CK en su propia clase y definí un protocolo de delegado con el que hice que se ajustara la clase principal. Dentro de los controladores de finalización, envié los datos recuperados de las llamadas de CK a donde los quiero almacenar a través de métodos de delegado.
Pan comido.
func getSomething(callback: (Array<AnyObject>) -> ()) {
var dataTask = NSURLSessionDataTask()
dataTask = session.dataTaskWithRequest(request) { (data, response, error) in
if (error == nil) {
var callbackArray = Array<MyObject>()
let responseDict = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as NSDictionary
let response = responseDict.objectForKey("response_key") as NSDictionary
let array = response.objectForKey("array_key") as NSArray
for item: AnyObject in array {
var arrayItem = MyObject(dict: item as NSDictionary)
callbackArray.append(arrayItem)
}
callback(callbackArray)
} else {
// handle an error
}
}
dataTask.resume()
}
Entonces podrías hacer algo como:
getSomething() { (response) in
if let responseArray = response as? Array<MyObject> {
self.somethings = responseArray
}
}