Skip to content

Instantly share code, notes, and snippets.

View swhitty's full-sized avatar

Simon Whitty swhitty

View GitHub Profile
@swhitty
swhitty / UniqueChanges.swift
Last active January 29, 2024 07:01
PropertyWrapper that can be applied to `Equatable` properties of `ObservableObject` to notify observers of unique changes.
/// PropertyWrapper that can be applied to `Equatable` properties of `ObservableObject` to notify observers of unique changes
@propertyWrapper
struct UniqueChanges<Element: Equatable> {
init(wrappedValue: Element) {
self._wrappedValue = wrappedValue
}
@available(*, unavailable, message: "@UniqueChanges can only be applied to types that conform to `ObservableObject`")
var wrappedValue: Element {
// ThrowingTaskGroup.waitForAll() behaviour was fixed in Swift 5.9
// This backports the Swift 5.9 behaviour to earlier versions
// https://github.com/apple/swift/pull/63016
public extension ThrowingTaskGroup {
#if compiler(>=5.9)
@available(*, deprecated, renamed: "waitForAll")
#endif
mutating func waitForAllFix() async throws {
@_implementationOnly import os
// Backports the Swift interface around os_unfair_lock_t available in recent Darwin platforms
// https://github.com/swhitty/AllocatedLock
//
@available(iOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
@available(tvOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
@available(watchOS, deprecated: 9, message: "use OSAllocatedUnfairLock directly")
@available(macOS, deprecated: 13.0, message: "use OSAllocatedUnfairLock directly")
public struct AllocatedLock<State>: @unchecked Sendable {
/// .handleEvents(onNext: { print($0) }) Similar to the Combine variant, but for AsyncSequence.
///
public extension AsyncSequence {
/// Attach event handlers to interation events of the sequence.
/// - Parameters:
/// - onInit: handler called when interator is created
/// - onNext: handler called when value is received
/// - onCompletion: handler called when sequence competes
extension AsyncSequence where Element: Hashable {
/// Sequence that emits unique elements once each
func unique() -> AsyncUniqueSequence<Self> {
AsyncUniqueSequence(self)
}
}
/// Sequence that only emits unique elements once.
/// While iterating, all emitted elements are retained within a `Set` to ensure uniqueness of each element emitted.
/// .print("🐡") Similar to the Combine variant, but for AsyncSequence.
///
/// ```
/// 🐡: makeAsyncIterator(): AsyncMapSequence<String>
/// 🐡: receive value: (1)
/// 🐡: receive value: (2)
/// 🐡: finished: AsyncMapSequence<String>
/// ```
///
import Combine
import Foundation
func copyValues<T>(at keyPaths: [PartialKeyPath<T>], from source: T, to destination: inout T) {
for keyPath in keyPaths.compactMap({ $0 as? any ValueCopyingKeyPath }) {
keyPath.copyValue(from: source, to: &destination)
}
}
extension _KeyValueCodingAndObservingPublishing where Self: NSObject {
@swhitty
swhitty / SVG.swift
Created March 8, 2022 10:10 — forked from ollieatkinson/SVG.swift
Utilise the private CoreSVG framework in Swift
import Darwin
import Foundation
import UIKit
@objc
class CGSVGDocument: NSObject { }
var CGSVGDocumentRetain: (@convention(c) (CGSVGDocument?) -> Unmanaged<CGSVGDocument>?) = load("CGSVGDocumentRetain")
var CGSVGDocumentRelease: (@convention(c) (CGSVGDocument?) -> Void) = load("CGSVGDocumentRelease")
var CGSVGDocumentCreateFromData: (@convention(c) (CFData?, CFDictionary?) -> Unmanaged<CGSVGDocument>?) = load("CGSVGDocumentCreateFromData")
import Combine
import RxSwift
import Foundation
extension ObservableType {
var publisher: RxPublisher<Self> {
RxPublisher(self)
}
}
import Foundation
/// @Awaiting wraps optional properties and projects an async function that waits
/// when `wrappedValue` is nil, until some value is set.
///
/// Throws `CancellationError` when task is cancelled.
///
/// ```
/// @Awaiting var name: String?
/// ...