Skip to content

Instantly share code, notes, and snippets.

@ahmedk92
Created August 19, 2020 09:49
Show Gist options
  • Save ahmedk92/b6c98d48cdb12f67b7992eed44de66f4 to your computer and use it in GitHub Desktop.
Save ahmedk92/b6c98d48cdb12f67b7992eed44de66f4 to your computer and use it in GitHub Desktop.
Combine Publisher for CADisplayLink
//
// CADisplayLinkPublisher.swift
// SwiftUIDemo
//
// Created by Ahmed Khalaf on 8/19/20.
//
// Credits: https://www.avanderlee.com/swift/custom-combine-publisher/
import UIKit
import Combine
final class CADisplayLinkSubscription<SubscriberType: Subscriber>: Subscription where SubscriberType.Input == CADisplayLink {
// MARK: - Public
init(subscriber: SubscriberType) {
self.subscriber = subscriber
self.displayLink = .init(target: self, selector: #selector(handleDisplayLink))
self.displayLink?.add(to: .main, forMode: .common)
}
// MARK: - Subscription
func request(_ demand: Subscribers.Demand) {
}
func cancel() {
subscriber = nil
displayLink?.invalidate()
displayLink = nil
}
// MARK: - Private
private var subscriber: SubscriberType?
private var displayLink: CADisplayLink?
@objc private func handleDisplayLink() {
guard
let displayLink = displayLink
else {
return
}
_ = subscriber?.receive(displayLink)
}
}
struct CADisplayLinkPublisher: Publisher {
typealias Output = CADisplayLink
typealias Failure = Never
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input {
subscriber.receive(subscription: CADisplayLinkSubscription(subscriber: subscriber))
}
}
extension CADisplayLink {
static var publisher: CADisplayLinkPublisher {
CADisplayLinkPublisher()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment