Multiple workers in Swift Command Line Tool
I mistakenly interpreted the locking thread for a hanging program. The work will execute just fine without a run loop. The code in the question will run fine, and blocking the main thread until the whole group has finished.
So say chunks
contains 4 items of workload, the following code spins up 4 concurrent workers, and then waits for all of the workers to finish:
let group = DispatchGroup()
let queue = DispatchQueue(label: "", attributes: .concurrent)
for chunk in chunk {
queue.async(group: group, execute: DispatchWorkItem() {
do_work(chunk)
})
}
_ = group.wait(timeout: .distantFuture)
Swift or Objective-C command line tool and text to speech not outputting audio
NSSpeechSynthesizer.isAnyApplicationSpeaking() waits until the speech is finished.
import Foundation
import AppKit
class Speaker: NSObject , NSSpeechSynthesizerDelegate {
var synth : NSSpeechSynthesizer!
func run() {
self.synth = NSSpeechSynthesizer.init()
self.synth.delegate = self
self.synth.startSpeakingString("First word")
while(NSSpeechSynthesizer.isAnyApplicationSpeaking() == true) {}
}
}
var speak : Speaker = Speaker.init()
speak.run()
Using NSURLSession from a Swift command line program
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 = DispatchSemaphore( value: 0 )
class Delegate : NSObject, URLSessionDataDelegate
{
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
print("got data \(String(data: data, encoding: .utf8 ) ?? "<empty>")");
sema.signal()
}
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: Delegate(), delegateQueue: nil )
guard let url = URL( string:"http://apple.com" ) else { fatalError("Could not create URL object") }
session.dataTask( with: url ).resume()
sema.wait()
How do you access command line arguments in Swift?
Apple has released the ArgumentParser
library for doing just this:
We’re delighted to announce
ArgumentParser
, a new open-source library that makes it straightforward — even enjoyable! — to parse command-line arguments in Swift.https://swift.org/blog/argument-parser/
Swift Argument Parser
https://github.com/apple/swift-argument-parser
Begin by declaring a type that defines the information you need to collect from the command line. Decorate each stored property with one of
ArgumentParser
's property wrappers, and declare conformance toParsableCommand
.The
ArgumentParser
library parses the command-line arguments, instantiates your command type, and then either executes your customrun()
method or exits with useful a message.
Waiting for asynchronous calls in a swift script
Thanks to Aaron Brager, who linked to
Multiple workers in Swift Command Line Tool ,
which is what I used to find my answer, using dispatch_groups to solve the problem.
Related Topics
How to Silence a Warning in Swift
Saving Webview to Pdf Returns Blank Image
Change the Value That Is Being Set in Variable's Willset Block
How to Determine the Type of a Variable in Swift
Intrinsiccontentsize() - Method Does Not Override Any Method from Its Superclass
Perform Assignment Only If Right Side Is Not Nil
Read-Only Properties of Protocols in Swift
What Is the Use of "Static" Keyword If "Let" Keyword Used to Define Constants/Immutables in Swift
Include Swiftui Views in Existing Uikit Application
Why .Pch File Not Available in Swift
Remove Element from Collection During Iteration with Foreach
How to Display Data from Firebase Faster
Delete Data from Coredata Swift
One-Line Closure Without Return Type