On 27 Oct 2016, at 13:01, Steven Harms via swift-users <swift-users@swift.org> wrote:
> At this point I'm going to have to confess that I need some help clarifying > my model. Quite. There two real issues here: * You don’t need to create a queue just to start a request. It’s fine to start the request from any context. Thus, your `queue.async(…)` call is not needed. * URLSession will run requests asynchronously, thus you need to prevent your process from terminating until the relevant requests are done. In a real program the framework you’re using typically does this for you. In a test project like this you have two options: - dispatchMain() — That is, just add a line containing `dispatchMain()` to the bottom of your ‘main’ code. - synthetic synchronous — Traditionally this is done using dispatch semaphores; I won’t show it here because a) you’ll find lots of example of it, and b) it’s not recommended, for obscure reasons related to QoS propagation. > 1. How did point "y" get fired twice? Or how did it happen not at all? I ran your code verbatim (except that I added a `dispatchMain()` at the end) on my Mac running 10.11.6, built with Xcode 8, and I didn’t see the second copy of `y`. > 2. How did my callback for dataTask *never* fire? Even if the connection task > *failed* the handler ought have fired, no? Because the process terminated before the request finished. > 3. I didn't want to bring this whole queue business into the picture, but it > appears that without it the program exits before the handler has a chance to > fire. Correct. > 4. Changing to a queue.sync from queue.async consistently produces the output > I expect, but does not fire my completionHandler still. Right, because that’s about how the request /starts/, not about how the request’s completion handler runs. > 5. Is there a canonical reference for doing this simplest of tasks? Here’s a minimal example of a command line tool that fetches a URL. --------------------------------------------------------------------------- import Foundation URLSession.shared.dataTask(with: URL(string: "http://www.example.com")!) { (data, response, error) in if let error = error { print("error: \(error)") exit(1) } else { let response = response as! HTTPURLResponse let data = data! print("status: \(response.statusCode)") for (key, value) in response.allHeaderFields { print("header: \(key) = \(value)") } print("body: \(data as NSData)") exit(0) } }.resume() dispatchMain() --------------------------------------------------------------------------- When I run this (same environment as above) I get this: status: 200 header: Date = Fri, 28 Oct 2016 08:02:04 GMT header: Content-Length = 606 header: Etag = "359670651" header: x-ec-custom-error = 1 header: Last-Modified = Fri, 09 Aug 2013 23:54:35 GMT header: Accept-Ranges = bytes header: Vary = Accept-Encoding header: X-Cache = HIT header: Content-Type = text/html header: Expires = Fri, 04 Nov 2016 08:02:04 GMT header: Server = ECS (ewr/15BD) header: Content-Encoding = gzip header: Cache-Control = max-age=604800 body: <3c21646f 63747970 65206874 6d6c3e0a 3c68746d …> The only weird thing in the code above is that `key` is of type `AnyHashable` rather than `String`. That’s because the type of `allHeaderFields` is wrong <rdar://problem/27805863>. Alas, I’m not set up to run this on Linux )-: Share and Enjoy -- Quinn "The Eskimo!" <http://www.apple.com/developer/> Apple Developer Relations, Developer Technical Support, Core OS/Hardware _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users