Skip to content

Instantly share code, notes, and snippets.

View swhitty's full-sized avatar

Simon Whitty swhitty

View GitHub Profile
@swhitty
swhitty / Mutex.swift
Last active September 7, 2024 06:04
Backports the Swift 6 type Mutex<Value> to all Apple platforms that support OSAllocatedUnfairLock
// Backports the Swift 6 type Mutex<Value> to Swift 5 and all Darwin platforms via OSAllocatedUnfairLock.
// Lightweight version of https://github.com/swhitty/swift-mutex
// Feel free to use any part of this gist.
// Note: ~Copyable are not supported
#if compiler(>=6)
@available(iOS, introduced: 16.0, deprecated: 18.0, message: "use Mutex from Synchronization module included with Swift 6")
@available(macOS, introduced: 13.0, deprecated: 15.0, message: "use Mutex from Synchronization module included with Swift 6")
public struct Mutex<Value>: @unchecked Sendable {
@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)
}
}