Skip to content

Instantly share code, notes, and snippets.

Avatar

Oliver Atkinson ollieatkinson

  • Sky
  • United Kingdom
View GitHub Profile
@ollieatkinson
ollieatkinson / AttributesOf.swift
Last active May 22, 2021
Composition of attributes and values for types in Swift
View AttributesOf.swift
struct AttributesOf<Object>: CustomStringConvertible {
enum Error: Swift.Error { case message(String) }
public typealias Assignment = (keyPath: AnyKeyPath, set: (Object) -> Void)
private(set) var assignments: [Assignment]
init(@AttributesOfBuilder<Object> _ builder: () throws -> [Assignment]) rethrows {
assignments = try builder()
@ollieatkinson
ollieatkinson / Dictionary+DeepMerge.swift
Last active May 21, 2021
DeepMerge two Dictionary's in Swift
View Dictionary+DeepMerge.swift
public enum DeepMergeUniquingPolicy {
case old, new
}
extension Dictionary {
public func deepMerging(_ other: Self, uniquingPolicy policy: DeepMergeUniquingPolicy = .new) -> Self {
(self as [Key: Any]).deepMerging(other as [Key: Any], uniquingPolicy: policy) as! Self
}
}
View String+Error.swift
extension Optional {
public func or(throw error: @autoclosure () -> Error) throws -> Wrapped {
guard let wrapped = self else { throw error() }
return wrapped
}
}
extension String {
@ollieatkinson
ollieatkinson / SVG.swift
Last active May 20, 2021
Utilise the private CoreSVG framework in Swift
View SVG.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")
@ollieatkinson
ollieatkinson / Publisher.swift
Created Apr 29, 2021
Useful extensions for Combine Publisher
View Publisher.swift
extension Publisher where Failure == Never {
public func sink<Root>(to handler: @escaping (Root) -> (Output) -> Void, on root: Root) -> AnyCancellable where Root: AnyObject {
sink{ [weak root] value in
guard let root = root else { return }
handler(root)(value)
}
}
@ollieatkinson
ollieatkinson / UIGestureRecognizer.Publisher.swift
Created Apr 29, 2021
Combine publisher for UIGestureRecognizer
View UIGestureRecognizer.Publisher.swift
extension UIView {
func publisher<G>(for gestureRecognizer: G) -> UIGestureRecognizer.Publisher<G> where G: UIGestureRecognizer {
UIGestureRecognizer.Publisher(gestureRecognizer: gestureRecognizer, view: self)
}
}
extension UIGestureRecognizer {
struct Publisher<G>: Combine.Publisher where G: UIGestureRecognizer {
@ollieatkinson
ollieatkinson / JSON.swift
Created Mar 15, 2021
Another JSON box implementation over `Any` type
View JSON.swift
struct JSON {
enum Index {
case ordinal(Int), key(String)
}
private(set) var any: Any?
init(_ any: Any? = nil) {
self.any = any
@ollieatkinson
ollieatkinson / KeyValuePairs.swift
Created Mar 8, 2021
Key value pairing with support for equality, hashing and coding
View KeyValuePairs.swift
extension Dictionary {
public typealias KeyValuePairs = [KeyValuePair<Key, Value>]
public var keyValuePairs: KeyValuePairs { map(KeyValuePair.init) }
}
extension Collection where Element: KeyValuePair_P {
public var dictionary: [Element.Key: Element.Value] { Dictionary(uniqueKeysWithValues: map(\.tuple)) }
}
public protocol KeyValuePair_P {
View AnyDictionary.swift
protocol AnyDictionary: Collection {
associatedtype Key: Hashable
associatedtype Keys
associatedtype Value
associatedtype Values
associatedtype Index
var keys: Keys { get }
var values: Values { get }
@ollieatkinson
ollieatkinson / AtomicCollection.swift
Created Dec 26, 2020
Atomic read/write access for collections
View AtomicCollection.swift
import Foundation
class AtomicCollection<C> where C: Collection {
var base: C
let queue: DispatchQueue
init(_ base: C, label: String, qos: DispatchQoS = .unspecified, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit, target: DispatchQueue? = nil) {
self.base = base
self.queue = DispatchQueue(