nsurlsession - consumir - Swift 3, URLSession dataTask completionHandler no llamado
urlsession swift 4 (5)
Hice una aplicación simple desde cero. (Xcode 8 beta 6 / swift 3) En el controlador pegué su código. (además de la creación de url ..) Veo todo en depurador:
ESTE ES IMPRESO
ESTE ES IMPRESO, TAMBIÉN
ESTOY DE VUELTA
así que parece funcionar.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let URLString = "https://apple.com"
let url = URL(string: URLString)
let request = URLRequest(url: url!)
ViewController.execTask(request: request) { (ok, obj) in
print("I AM BACK")
}
}
private class func execTask(request: URLRequest, taskCallback: @escaping (Bool,
AnyObject?) -> ()) {
let session = URLSession(configuration: URLSessionConfiguration.default)
print("THIS LINE IS PRINTED")
let task = session.dataTask(with: request, completionHandler: {(data, response, error) -> Void in
if let data = data {
print("THIS ONE IS PRINTED, TOO")
let json = try? JSONSerialization.jsonObject(with: data, options: [])
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
taskCallback(true, json as AnyObject?)
} else {
taskCallback(false, json as AnyObject?)
}
}
})
task.resume()
}
}
Estoy escribiendo una biblioteca, así que no uso UIKit, incluso en mi aplicación iOS el mismo código funciona, pero cuando lo ejecuto en la línea de comando no. En PlayGround también parece funcionar.
Por alguna razón, la devolución de llamada no se activa, por lo que las instrucciones de impresión no se están ejecutando.
internal class func post(request: URLRequest, responseCallback: @escaping (Bool, AnyObject?) -> ()) {
execTask(request: request, taskCallback: { (status, resp) -> Void in
responseCallback(status, resp)
})
}
internal class func clientURLRequest(url: URL, path: String, method: RequestMethod.RawValue, params: Dictionary<String, Any>? = nil) -> URLRequest {
var request = URLRequest(url: url)
request.httpMethod = method
do {
let jsonData = try JSONSerialization.data(withJSONObject: (params! as [String : Any]), options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
} catch let error as NSError {
print(error)
}
return request
}
private class func execTask(request: URLRequest, taskCallback: @escaping (Bool,
AnyObject?) -> ()) {
let session = URLSession(configuration: URLSessionConfiguration.default)
print("THIS LINE IS PRINTED")
let task = session.dataTask(with: request, completionHandler: {(data, response, error) -> Void in
if let data = data {
print("THIS ONE IS NOT PRINTED")
let json = try? JSONSerialization.jsonObject(with: data, options: [])
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
taskCallback(true, json as AnyObject?)
} else {
taskCallback(false, json as AnyObject?)
}
}
})
task.resume()
}
Ediciones -: estoy escribiendo una biblioteca, entonces no uso UIKit, incluso en mi aplicación iOS el mismo código funciona, pero cuando lo ejecuto en la línea de comando no. En PlayGround también parece funcionar.
let dataTask = session.dataTask(with: request, completionHandler: {data, response,error -> Void in
print("Request : /(response)")
let res = response as! HTTPURLResponse
print("Status Code : /(res.statusCode)")
let strResponse = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Response String :/(strResponse)")
})
dataTask.resume()
Swift 3.0
Simplemente copie el código debajo de su controlador de vista.
@IBAction func btnNewApplicationPressed (_ sender: UIButton) {
callWebService()
}
func callWebService() {
// Show MBProgressHUD Here
var config :URLSessionConfiguration!
var urlSession :URLSession!
config = URLSessionConfiguration.default
urlSession = URLSession(configuration: config)
// MARK:- HeaderField
let HTTPHeaderField_ContentType = "Content-Type"
// MARK:- ContentType
let ContentType_ApplicationJson = "application/json"
//MARK: HTTPMethod
let HTTPMethod_Get = "GET"
let callURL = URL.init(string: "https://itunes.apple.com/in/rss/newapplications/limit=10/json")
var request = URLRequest.init(url: callURL!)
request.timeoutInterval = 60.0 // TimeoutInterval in Second
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = HTTPMethod_Get
let dataTask = urlSession.dataTask(with: request) { (data,response,error) in
if error != nil{
return
}
do {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Result",resultJson!)
} catch {
print("Error -> /(error)")
}
}
dataTask.resume()
}
¿Los cambios sugeridos aquí, funciona ahora?
Usando NSURLSession desde un programa de línea de comando Swift
var sema = DispatchSemaphore( value: 0 )
private func execTask(request: URLRequest, taskCallback: @escaping (Bool,
AnyObject?) -> ()) {
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil )
session.dataTask(with: request) {(data, response, error) -> Void in
if let data = data {
let json = try? JSONSerialization.jsonObject(with: data, options: [])
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
taskCallback(true, json as AnyObject?)
} else {
taskCallback(false, json as AnyObject?)
}
}
}.resume()
sema.wait()
}
Sé que es tarde para la respuesta, pero en caso de que no haya resuelto el problema o no haya tenido problemas en otros lugares, intente esto.
Debe guardar la variable de sesión fuera del alcance del método (conviértalo en una variable de instancia). Como lo definió localmente en el alcance de la función. Es desasignado antes de que se pueda invocar el controlador de finalización, recuerde que el manejador de finalización no puede retener su objeto de sesión y después de la ejecución del bucle de ejecución, el recolector de elementos no utilizados desasignará su objeto de sesión. Necesitamos retener esos objetos siempre que deseemos una devolución de llamada de los delegados o del manejador de finalización.
self.session = URLSession(configuration: URLSessionConfiguration.default)