Skip to content

Instantly share code, notes, and snippets.

View ollieatkinson's full-sized avatar
🌴
On vacation

Oliver Atkinson ollieatkinson

🌴
On vacation
View GitHub Profile
@ollieatkinson
ollieatkinson / Publishers+RetryDelay.swift
Last active January 31, 2025 11:28
Add a delay in-between each Combine retry, offering a timing function and default implementations for none, constant seconds and exponential backoff
import Combine
import Foundation
extension Publisher {
public func retry<S: Scheduler>(
_ max: Int = Int.max,
delay: Publishers.RetryDelay<Self, S>.TimingFunction,
scheduler: S
) -> Publishers.RetryDelay<Self, S> {
@ollieatkinson
ollieatkinson / Executable.swift
Created August 17, 2021 15:41
Simply execute shell commands from Swift
public struct Executable {
let url: URL
public init(_ filePath: String) {
url = URL(fileURLWithPath: filePath)
}
public init(_ url: URL) {
self.url = url
@ollieatkinson
ollieatkinson / CombineLatestCollection.swift
Last active June 29, 2021 13:36
`combineLatest()` on `Collection` where elements are Publishers
import Combine
import Foundation
extension Collection where Element: Publisher {
public func combineLatest() -> CombineLatestCollection<Self> {
CombineLatestCollection(self)
}
}
@ollieatkinson
ollieatkinson / Decodable+ContainerType.swift
Last active June 19, 2021 10:21
Encoding / Decoding Container Types
enum DecodingContainer: String {
case keyed
case unkeyed
case singleValue
}
extension Decodable {
static var container: DecodingContainer {
do {
@ollieatkinson
ollieatkinson / AttributesOf.swift
Last active March 10, 2023 17:41
Composition of attributes and values for types in 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 July 31, 2022 19:29
DeepMerge and DeepMerge for Dictionary's in Swift
public struct DeepMapOptions: OptionSet {
public let rawValue: UInt
public init(rawValue: UInt) { self.rawValue = rawValue }
public static let mappingOverArrays = DeepMapOptions(rawValue: 1 << 0)
public static let all: DeepMapOptions = [.mappingOverArrays]
}
extension Dictionary where Value == Any {
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 June 27, 2026 03:45
Utilise the private CoreSVG framework in Swift
import Darwin
import Foundation
import UIKit
// https://github.com/xybp888/iOS-SDKs/blob/master/iPhoneOS17.1.sdk/System/Library/PrivateFrameworks/CoreSVG.framework/CoreSVG.tbd
// https://developer.limneos.net/index.php?ios=17.1&framework=UIKitCore.framework&header=UIImage.h
@objc
class CGSVGDocument: NSObject { }
@ollieatkinson
ollieatkinson / Publisher.swift
Created April 29, 2021 11:06
Useful extensions for Combine Publisher
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 April 29, 2021 10:48
Combine publisher for UIGestureRecognizer
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 {