NSURLConnection sendAsynchronousRequest no puede obtener variables fuera de cierre

Estoy tratando de obtener una respuesta de texto simple de una página de PHP utilizando POST. Tengo el siguiente código:

func post(url: String, info: String) -> String { var URL: NSURL = NSURL(string: url)! var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL) var output = "Nothing Returned"; request.HTTPMethod = "POST"; var bodyData = info; request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){ response, data, error in output = (NSString(data: data, encoding: NSUTF8StringEncoding))! } return output } 

Si bien este código no arroja ningún error, cuando lo llamo así:

 println(post(url, info: data)) 

Solo se imprime: “Nothing Returned”, aunque si tuviera que cambiar la línea:

 output = (NSString(data: data, encoding: NSUTF8StringEncoding))! 

a esto:

 println((NSString(data: data, encoding: NSUTF8StringEncoding))) 

imprime la respuesta adecuada. ¿Estoy haciendo algo mal con mis variables aquí?

Esto está llamando a la función asíncrona que está utilizando un locking / cierre de manejador de finalización. Por lo tanto, debe emplear el patrón de controlador de finalización en su propio código. Esto consiste en cambiar el tipo de devolución de método a Void y agregar un nuevo cierre de completionHandler que se llamará cuando se realice la llamada asincrónica:

 func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) { let URL = NSURL(string: url)! let request = NSMutableURLRequest(URL:URL) request.HTTPMethod = "POST" let bodyData = info request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in guard data != nil else { completionHandler(nil, error) return } completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil) } } 

O bien, dado que NSURLConnection está ahora obsoleto formalmente, podría ser mejor utilizar NSURLSession :

 func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) -> NSURLSessionTask { let URL = NSURL(string: url)! let request = NSMutableURLRequest(URL:URL) request.HTTPMethod = "POST" let bodyData = info request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_main_queue()) { guard data != nil else { completionHandler(nil, error) return } completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil) } } task.resume() return task } 

Y lo llamas así:

 post(url, info: info) { responseString, error in guard responseString != nil else { print(error) return } // use responseString here } // but don't try to use response string here ... the above closure will be called // asynchronously (ie later) 

Tenga en cuenta que, para mantener esto simple, he empleado la syntax de cierre final (vea la sección Cierre de rastreo del lenguaje de progtwigción Swift: cierres ), pero con suerte ilustra la idea: no puede devolver el resultado de un método asíncrono, así que proporcione un cierre de controlador de finalización que se llamará cuando se realiza el método asíncrono.