Created
June 25, 2019 14:01
-
-
Save trilliwon/63a9d7561107bb7c23fd007c94c3e55a to your computer and use it in GitHub Desktop.
AVSpeechSynthesizer+Rx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if os(iOS) | |
import AVFoundation | |
import RxCocoa | |
import RxSwift | |
extension AVSpeechSynthesizer: HasDelegate { | |
public typealias Delegate = AVSpeechSynthesizerDelegate | |
} | |
open class RxAVSpeechSynthesizerDelegateProxy: DelegateProxy<AVSpeechSynthesizer, AVSpeechSynthesizerDelegate>, DelegateProxyType, AVSpeechSynthesizerDelegate { | |
/// Typed parent object. | |
public weak private(set) var speechSynthesizer: AVSpeechSynthesizer? | |
/// - parameter speechSynthesizer: Parent object for delegate proxy. | |
public init(speechSynthesizer: ParentObject) { | |
self.speechSynthesizer = speechSynthesizer | |
super.init(parentObject: speechSynthesizer, delegateProxy: RxAVSpeechSynthesizerDelegateProxy.self) | |
} | |
// Register known implementationss | |
public static func registerKnownImplementations() { | |
self.register { RxAVSpeechSynthesizerDelegateProxy(speechSynthesizer: $0) } | |
} | |
} | |
public extension Reactive where Base: AVSpeechSynthesizer { | |
/// Reactive wrapper for `delegate`. | |
/// For more information take a look at `DelegateProxyType` protocol documentation. | |
var delegate: DelegateProxy<AVSpeechSynthesizer, AVSpeechSynthesizerDelegate> { | |
return RxAVSpeechSynthesizerDelegateProxy.proxy(for: base) | |
} | |
/// Installs delegate as forwarding delegate on `delegate`. | |
/// Delegate won't be retained. | |
/// | |
/// It enables using normal delegate mechanism with reactive delegate mechanism. | |
/// | |
/// - parameter delegate: Delegate object. | |
/// - returns: Disposable object that can be used to unbind the delegate. | |
func setDelegate(_ delegate: AVSpeechSynthesizerDelegate) -> Disposable { | |
return RxAVSpeechSynthesizerDelegateProxy | |
.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:utterance:` | |
*/ | |
var started: ControlEvent<AVSpeechUtterance> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:didStart:))) | |
.map { try castOrThrow(AVSpeechUtterance.self, $0[1]) } | |
return ControlEvent(events: source) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:utterance:` | |
*/ | |
var finished: ControlEvent<AVSpeechUtterance> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:didFinish:))) | |
.map { try castOrThrow(AVSpeechUtterance.self, $0[1]) } | |
return ControlEvent(events: source) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:utterance:` | |
*/ | |
var paused: ControlEvent<AVSpeechUtterance> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:didPause:))) | |
.map { try castOrThrow(AVSpeechUtterance.self, $0[1]) } | |
return ControlEvent(events: source) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:utterance:` | |
*/ | |
var continued: ControlEvent<AVSpeechUtterance> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:didContinue:))) | |
.map { try castOrThrow(AVSpeechUtterance.self, $0[1]) } | |
return ControlEvent(events: source) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:utterance:` | |
*/ | |
var canceled: ControlEvent<AVSpeechUtterance> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:didCancel:))) | |
.map { try castOrThrow(AVSpeechUtterance.self, $0[1]) } | |
return ControlEvent(events: source) | |
} | |
/** | |
Reactive wrapper for `delegate` message `synthesizer:characterRange:utterance:` | |
*/ | |
var speekRange: ControlEvent<(characterRange: NSRange, utterance: AVSpeechUtterance)> { | |
let source = delegate | |
.methodInvoked(#selector(AVSpeechSynthesizerDelegate.speechSynthesizer(_:willSpeakRangeOfSpeechString:utterance:))) | |
.map { (characterRange: try castOrThrow(NSRange.self, $0[1]), utterance: try castOrThrow(AVSpeechUtterance.self, $0[2])) } | |
return ControlEvent(events: source) | |
} | |
} | |
func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T { | |
guard let returnValue = object as? T else { | |
throw RxCocoaError.castingError(object: object, targetType: resultType) | |
} | |
return returnValue | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment