Swift 3: URLSession / URLRequest not working

I'm still trying to convert our application from Swift 2 to Swift 3 because I am being forced to, because all of our Apple devices are now running iOS 10.

I went through the code conversion and thought that I was fine, trying to debug my JSON problems (posted in another question), now I am dealing with requests that are not even sent.

let params: [String:AnyObject] = [ "email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject ] let requestParams: [String:AnyObject] = [ "action":"601" as AnyObject, "params":params as AnyObject ] do { let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[]) var request = URLRequest(url: URL(string: "http://domain.tld/path/")!) request.httpBody = requestObject request.httpMethod = "POST" let config = URLSessionConfiguration.default let session = URLSession(configuration: config) NSLog("Got here?") session.dataTask(with: request) {data, response, error in guard let data = data, error == nil else { print("error=\(error)") return } NSLog("Got here 3?") let object:JSON = JSON(data:data) NSLog("Object: \(object)") }.resume() NSLog("Got here 4?") } catch { NSLog("Got here catch?") } NSLog("End of getUser") 

The above code gives the following output:

 2016-10-04 13:00:12.011969 OneTouch[1589:623015] [DYMTLInitPlatform] platform initialization successful 2016-10-04 13:00:12.264319 OneTouch[1589:622954] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2016-10-04 13:00:12.265321 OneTouch[1589:622954] [MC] Reading from public effective user settings. 2016-10-04 13:00:12.295055 OneTouch[1589:622954] Got here? 2016-10-04 13:00:12.295445 OneTouch[1589:622954] Got here 4? 2016-10-04 13:00:12.295515 OneTouch[1589:622954] End of getUser (lldb) 

This means that the request is not even made. Is there any key that I have to add to PLIST again? It starts to get annoying.

Below is my old code, and it doesn't even work anymore:

 let params: [String:AnyObject] = [ "email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject ] let requestParams: [String:AnyObject] = [ "action":"601" as AnyObject, "params":params as AnyObject ] do { let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[]) let request = NSMutableURLRequest(url: URL(string: "http://domain.tld/path/" as String)!, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20) request.httpBody = requestObject request.httpMethod = "POST" NSLog("Got here?") let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in if error != nil { NSLog("Got here 2?") } NSLog("Got here 3?") let object:JSON = JSON(data:data!) NSLog("Object: \(object)") }) NSLog("Got here 4?") task.resume() } catch { NSLog("Got here catch?") } NSLog("End of getUser") 

The code above gives the same result as another code!

+6
source share
1 answer

If you set a breakpoint immediately after calling getUser , the URLSession task completion handler, which runs asynchronously (that is, usually ends later if the request did not complete immediately or was not satisfied with any cached response), might not have been called .

If you place a breakpoint inside the dataTask completion dataTask , you should see your data at that point.


Personally, I would give getUser a completion handler so that you know when this will be done:

 func getUser(completionHandler: @escaping (JSON?, Error?) -> Void) { let params = [ "email":"\(preferences.string(forKey: "preference_email")!)" ] let requestParams: [String: Any] = [ "action": "601", "params": params ] do { let requestObject = try JSONSerialization.data(withJSONObject: requestParams) var request = URLRequest(url: URL(string: "http://domain.tld/path/")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 20) request.httpBody = requestObject request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept") let task = URLSession.shared.dataTask(with: request) {data, response, error in guard let data = data, error == nil else { completionHandler(nil, error) return } completionHandler(JSON(data: data), nil) } task.resume() } catch { completionHandler(nil, error) } } 

Then, when you call it, you can do something like:

 getUser { json, error in guard let json = json else { print(error) return } // do something with json print(json) } 

And just put your breakpoint in the getUser completion getUser . And remember that you have no assurances that the completion handler will be launched in the main queue or not, so you will need to send it to the dispatcher, as well as the UI, or simulate updates back to the main queue.

0
source

All Articles