Skip to content

Instantly share code, notes, and snippets.

View jacobsapps's full-sized avatar

Jacob Bartlett jacobsapps

View GitHub Profile
extension CADisplayLink {
static func events(mode: RunLoop.Mode = .default) -> AsyncStream<CADisplayLink> {
AsyncStream { continuation in
let displayLink = CADisplayLink(
target: DisplayLinkWrapper(continuation),
selector: #selector(DisplayLinkWrapper.tick)
)
displayLink.add(to: .main, forMode: mode)
continuation.onTermination = { @Sendable _ in
displayLink.invalidate()
@State private var fps: Double = 0
@State private var lastTimestamp: TimeInterval = 0
private let smoothingFactor: Double = 0.1
// ...
.task {
for await link in CADisplayLink.events() {
updateFPS(link)
}
private var continuation:
AsyncThrowingStream<Double, Error>.Continuation?
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
guard let continuation else { return }
func downloadStream() -> AsyncThrowingStream<Double, Error> {
AsyncThrowingStream { continuation in
Task {
var percentage = 0.0
while percentage < 70 {
try await Task.sleep(for: .milliseconds(10))
let bits = Double.random(in: 0...0.3)
percentage += bits
continuation.yield(with: .success(percentage))
}
@State private var progress: Double = 0
@State private var showError: Bool = false
// ...
.task {
do {
for try await percentage in DownloadAPI.downloadStream() {
progress = percentage
}
func locationManager(_ manager: CLLocationManager,
didUpdateHeading newHeading: CLHeading) {
rotationCallback?(-newHeading.magneticHeading)
}
final class LocationManager: CLLocationManager, CLLocationManagerDelegate {
private var rotationCallback: ((Double) -> Void)?
var rotationAngleStream: AsyncStream<Double> {
AsyncStream(bufferingPolicy: .bufferingNewest(1)) { continuation in
rotationCallback = {
continuation.yield($0)
}
}
@State private var rotationAngle: Angle = .degrees(0)
// ...
.task {
for await angle in LocationManager.shared.rotationAngleStream {
rotationAngle = Angle.degrees(angle)
}
}
struct Counter: AsyncSequence {
typealias Element = Int
let howHigh: Int
struct AsyncIterator: AsyncIteratorProtocol {
let howHigh: Int
var current = 1
mutating func next() async -> Int? {
guard current <= howHigh else {
.task {
for try await nextValue in asyncSequence {
print(nextValue)
}
}