I'm converting a Swift MacOS command-line tool/daemon to use Swift-NIO for networking. This is my first Swift-NIO project.
The tool fires a timer every 0.1 second. Here's the line at the bottom of main.swift which fires up the daemon/runloop, prior to the Swift-NIO conversion:
RunLoop.current.run()
Here's the timer in my Universe.swift class init(). There is always exactly one instance of this class:
timer = Timer(timeInterval: 1.0 / updatesPerSecond, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
timer?.tolerance = 0.3 / updatesPerSecond
debugPrint("Timer initialized")
if let timer = timer {
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
}
In this configuration the timer fires 10 times per second as expected. But if I get any network input my Swift-NIO library crashes because its not in the expected event loop.
In Swift-NIO, I'm supposed to add a channel.closeFuture.wait() line to the bottom of my main.swift:
// This will never unblock as we don't close the ServerChannel.
try channel.closeFuture.wait()
RunLoop.current.run()
That solves the Swift-NIO crash, but then I never get to my timer RunLoop, so my timer doesn't fire.
How can I use Swift-NIO to receive (and send) network data, while still having a timer running?
If it helps, the full open source for this project is at https://github.com/darrellroot/netrek-server-swift.