How to exit a runloop?

swift, swift3

Solution

For a command line interface use this pattern and add a completion handler to your AsyncNetworkingStuff (thanks to Rob for code improvement):

print("start")

let runLoop = CFRunLoopGetCurrent()
startAsyncNetworkingStuff() { result in 
   CFRunLoopStop(runLoop)
}

CFRunLoopRun()
print("end")
exit(EXIT_SUCCESS)

Please don't use ugly `while` loops.

Update:

In Swift 5.5+ with async/await it has become much more comfortable. There's no need anymore to maintain the run loop.

Rename the file `main.swift` as something else and use the `@main` attribute like in a normal application.

@main
struct CLI {

    static func main() async throws {
        let result = await startAsyncNetworkingStuff()
        // do something with result 
    }
}

The name of the struct is arbitrary, the static function `main` is mandatory and is the entry point.

Problem

So, I have a Swift command-line program: ``` import Foundation print("start") startAsyncNetworkingStuff() RunLoop.current.run() print("end") ``` The code compiles without error. The async networking code runs just fine, fetches all its data, prints the result, and eventually calls its completion function. How do I get that completion function to break out of above current runloop so that the last "end" gets printed? Added: Replacing RunLoop.current.run() with the following: ``` print("start") var shouldKeepRunning = true startAsyncNetworkingStuff() let runLoop = RunLoop.current while ( shouldKeepRunning && runLoop.run(mode: .defaultRunLoopMode, before: .distantFuture ) ) { } print("end") ``` Setting ``` shouldKeepRunning = false ``` in the async network completion function still does not result in "end" getting printed. (This was checked by bracketing the shouldKeepRunning = false statement with print statements which actually do print to console). What is missing?

Original source