Fred Clausen Fred Clausen - 5 months ago 28
Swift Question

Using NSURLSession from a Swift command line program

I'm trying to test a little proof-of-concept command line app prior to integrating it into a larger app. What I'm trying to do is download some data using NSURLSession using this example. However it appears that if I use the examples given in a simple OS X command line app then the app exits prior to the data being retrieved.

How can I download data from a stand-alone command line app using NSURLSession? What I've read about is using NSRunLoop however I've not yet found a clear example in Swift so if NSRunLoop is actually the way to go then any examples would be appreciated.

Any other strategies for downloading data from a URL for a Swift command line app is also welcome (infinite while loop?).

Answer

You can use a semaphore to block the current thread and wait for your URL session to finish.

Create the semaphore, kick off your URL session, then wait on the semaphore. From your URL session completion callback, signal the semaphore.

You could use a global flag (declare a volatile boolean variable) and poll that from a while loop, but that is less optimal. For one thing, you're burning CPU cycles unnecessarily.

Here's a quick example I did using a playground:

import Foundation

var sema = dispatch_semaphore_create( 0 )

class Delegate : NSObject, NSURLSessionDataDelegate
{
    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)
    {
        dispatch_semaphore_signal( sema )
    }
}

let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: Delegate(), delegateQueue: nil )

 if let url = NSURL( string:"http://apple.com" )
 {
    session.dataTaskWithURL( url ).resume()
 }

dispatch_semaphore_wait( sema, DISPATCH_TIME_FOREVER )
Comments