Skip to content

Instantly share code, notes, and snippets.

View swhitty's full-sized avatar

Simon Whitty swhitty

View GitHub Profile
struct AnyEquatable: Equatable {
let base: Any
let isEqual: (_ other: AnyEquatable) -> Bool
init<T: Equatable>(_ base: T) {
self.base = base
self.isEqual = { base == $0.base as? T }
}
public static func ==(lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
@swhitty
swhitty / CGPathApply.swift
Created February 27, 2017 11:15
Bridges CoreGraphics.CGPathApplierFunction with a standard Swift closure
extension CGPath {
func apply(action: @escaping (CGPathElement)->()) {
var action = action
apply(info: &action) {
let action = $0!.bindMemory(to: ((CGPathElement)->()).self, capacity: 1).pointee
action($1.pointee)
}
}
}
@swhitty
swhitty / WeakSet.swift
Last active February 12, 2021 22:05
Swift container that weakly holds references to objects.
import Foundation
public struct WeakSet<Element>: Sequence, ExpressibleByArrayLiteral, CustomStringConvertible where Element: AnyObject {
private var storage = Set<Box>()
public init(_ members: [Element]) {
members.forEach { insert($0) }
}
extension CGPattern {
static func make(bounds: CGRect,
matrix: CGAffineTransform,
step: CGSize,
tiling: CGPatternTiling,
isColored: Bool,
draw: @escaping (CGContext) -> Void) -> CGPattern {
let drawPattern: CGPatternDrawPatternCallback = { info, ctx in
import CoreGraphics
extension CGPath {
// Creates a smooth CGPath line between supplied points.
//
// Typical Polyline, straight line from point to point.
//
// /\
// __ ___/ \ /
import UIKit
public extension UIApplication {
// When unit testing some UIKit accessibility label properties are not updated until either;
// - Accessibility Inspector is connected to the specific simulator once, then closed. 🤷🏻‍♂️
// - Calling accessibilityActivate() one time.
func activateSimulatorForAccessibilityTesting() {
accessibilityActivate()
@swhitty
swhitty / Task+GroupOperations.swift
Last active January 13, 2021 00:20
Helper to make concurrent task group with any number of operations
import _Concurrency
extension Task {
// Create group with n tasks, executed concurrently.
// Returned array preserves original order of operations.
static func withGroup<TaskResult>(operations: [() async throws -> TaskResult]) async throws -> [TaskResult] {
return try await Task.withGroup(resultType: (Int, TaskResult).self) { group in
for (idx, provider) in operations.enumerated() {
await group.add {
import Combine
public extension Publisher {
/// Converts a publisher's output into the most recent output of another publisher.
///
/// - parameter other: A publisher that will provide the latest value
/// - returns: A publisher that emits the latest ouput of another publisher
func withLatestFrom<Other: Publisher>(_ other: Other) -> WithLatestFrom<Self, Other, Other.Output> {
import Combine
extension Publisher where Failure == Never {
/// Converts a publisher into a `Driver`
func driver() -> Driver<Output> { Driver(self) }
}
extension Driver {
func driver() -> Driver<Output> { self }
import Combine
// `UIScheduler` eagerly executes actions on the current queue if
// it is the main thread, avoiding unnecessary async behaviour.
// If the current queue is not the main thread, then the action is
// then scheduled on the main queue asynchonously.
//
// `DispatchQueue` schedulers execute all actions asynchronously.
//
struct UIScheduler: Scheduler {