Je suis en train d'écrire une bibliothèque, donc je n'utilise pas UIKit. Même dans mon application iOS, le même code fonctionne, mais lorsque j'exécute en ligne de commande, il ne fonctionne pas. En PlayGround aussi, il semble fonctionner.
Pour une raison quelconque, le rappel n'est pas déclenché, les instructions d'impression ne s'exécutent donc pas.
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()
}
Modifications -: J'écris une bibliothèque, je n'utilise donc pas UIKit. Même dans mon application iOS, le même code fonctionne, mais ne fonctionne pas lorsque j'exécute en ligne de commande. En PlayGround aussi, il semble fonctionner.
J'ai fait une application simple à partir de zéro. (Xcode 8 beta 6/Swift 3) Dans le contrôleur, j'ai collé votre code. (plus création d'URL ..) Je vois tout dans le débogueur:
CELUI-CI IS IMPRIME
CELUI-CI IS IMPRIME AUSSI
JE SUIS DE RETOUR
il semble donc travailler.
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()
}
}
Est-ce que les changements suggérés ici, ça fonctionne maintenant.
Utilisation de NSURLSession à partir d'un programme de ligne de commande 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()
}
Je sais qu'il est tard pour la réponse, mais si vous ne comprenez pas le problème ou si vous ne le rencontrez pas ailleurs, essayons.
Vous devez enregistrer la variable de session en dehors de la méthode (en faire une variable d'instance). Depuis que vous l'avez défini localement dans la portée de la fonction. Son gestionnaire get désalloué avant l'achèvement du processus d'achèvement peut être appelé. N'oubliez pas que le gestionnaire d'achèvement ne peut pas conserver votre objet de session. Après l'exécution de la boucle d'exécution, Garbage Collector désaffectera votre objet de session. Nous devons conserver de tels objets chaque fois que nous voulons être rappelés par des délégués ou par un gestionnaire d'achèvement.
self.session = URLSession(configuration: URLSessionConfiguration.default)
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()