Skip to content

Instantly share code, notes, and snippets.

@markst
Created July 17, 2023 00:37
Show Gist options
  • Save markst/eb07fbab8acb52a0c2901adc50e8f97a to your computer and use it in GitHub Desktop.
Save markst/eb07fbab8acb52a0c2901adc50e8f97a to your computer and use it in GitHub Desktop.
Wrap `GCKRequestDelegate` in a Combine `Subscriber`
import Combine
import GoogleCast
struct GCKRequestPublisher: Publisher {
typealias Output = Void
typealias Failure = Error
let request: GCKRequest
init(request: GCKRequest) {
self.request = request
}
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input {
let subscription = GCKRequestSubscription(request: request, subscriber: subscriber)
subscriber.receive(subscription: subscription)
}
}
class GCKRequestSubscription<S: Subscriber>: NSObject, GCKRequestDelegate, Subscription where S.Input == Void, S.Failure == Error {
var subscriber: S?
let request: GCKRequest
enum GCKRequestError: Error {
case error(GCKError)
case abort(GCKRequestAbortReason)
}
init(request: GCKRequest, subscriber: S) {
self.subscriber = subscriber
self.request = request
super.init()
self.request.delegate = self
}
func request(_ demand: Subscribers.Demand) { }
func cancel() {
request.cancel()
subscriber = nil
}
// MARK: - GCKRequestDelegate
func requestDidComplete(_ request: GCKRequest) {
subscriber?.receive(completion: .finished)
}
func request(_ request: GCKRequest, didFailWithError error: GCKError) {
subscriber?.receive(completion: .failure(GCKRequestError.error(error)))
}
func request(_ request: GCKRequest, didAbortWith abortReason: GCKRequestAbortReason) {
subscriber?.receive(completion: .failure(GCKRequestError.abort(abortReason)))
}
}
@markst
Copy link
Author

markst commented Jul 17, 2023

Usage:

extension GCKRequest {
    func publisher() -> GCKRequestPublisher {
        return GCKRequestPublisher(request: self)
    }
}
remoteMediaClient
    .seek(with: seekOptions)
    .publisher()
    .materialize()
    .sink { event in
        switch event {
        case .value:
            debugPrint("Success")
        case .failure(let error):
            debugPrint("Failure: \(error)")
        case .finished:
            debugPrint("Finished")
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment