Skip to content

Instantly share code, notes, and snippets.

@trilliwon
Last active December 17, 2018 15:29
Show Gist options
  • Save trilliwon/3dfa8b301473dfb69340480267b82571 to your computer and use it in GitHub Desktop.
Save trilliwon/3dfa8b301473dfb69340480267b82571 to your computer and use it in GitHub Desktop.
//
// RxAVSpeechSynthesizerDelegate.swift
// Pomodoro
//
// Created by Won on 17/12/2018.
// Copyright © 2018 won. All rights reserved.
//
#if os(iOS)
import AVFoundation
import RxAtomic
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