Skip to content

Instantly share code, notes, and snippets.

@jasdev
Last active Apr 11, 2021
Embed
What would you like to do?
Abbreviated form of SpeechClient.live
import Combine
import ComposableArchitecture
import Speech
extension SpeechClient {
static let live = SpeechClient(
cancelTask: { id in
.fireAndForget {
dependencies[id]?.cancel()
dependencies[id] = nil
}
},
finishTask: { id in
.fireAndForget {
dependencies[id]?.finish()
dependencies[id]?.subscriber.send(completion: .finished)
dependencies[id] = nil
}
},
recognitionTask: { id, request in
Effect.run { subscriber in
let cancellable = AnyCancellable {
dependencies[id]?.cancel()
dependencies[id] = nil
}
let speechRecognizer = //
let speechRecognizerDelegate = //
speechRecognizer.delegate = speechRecognizerDelegate
let audioEngine = //
//
let inputNode = audioEngine.inputNode
let recognitionTask = //
dependencies[id] = SpeechDependencies(
audioEngine: audioEngine,
inputNode: inputNode,
recognitionTask: recognitionTask,
speechRecognizer: speechRecognizer,
speechRecognizerDelegate: speechRecognizerDelegate,
subscriber: subscriber
)
//
return cancellable
}
.cancellable(id: id)
},
requestAuthorization: { /**/ }
)
}
private struct SpeechDependencies {
let audioEngine: AVAudioEngine
let inputNode: AVAudioInputNode
let recognitionTask: SFSpeechRecognitionTask
let speechRecognizer: SFSpeechRecognizer
let speechRecognizerDelegate: SpeechRecognizerDelegate
let subscriber: Effect<SpeechClient.Action, SpeechClient.Error>.Subscriber
func finish() {
self.audioEngine.stop()
self.inputNode.removeTap(onBus: 0)
self.recognitionTask.finish()
}
func cancel() {
self.audioEngine.stop()
self.inputNode.removeTap(onBus: 0)
self.recognitionTask.cancel()
}
}
private var dependencies: [AnyHashable: SpeechDependencies] = [:] // ⇐ This lil’ bub.
private class SpeechRecognizerDelegate: NSObject, SFSpeechRecognizerDelegate { /**/ }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment