Skip to content

Instantly share code, notes, and snippets.

View IanKeen's full-sized avatar
🏂

Ian Keen IanKeen

🏂
View GitHub Profile
@IanKeen
IanKeen / Lazy.swift
Last active January 9, 2024 08:41
Lazy<T>
class Lazy<T> {
private(set) var created: Bool = false
private(set) lazy var value: T = {
created = true
return builder()
}()
private var builder: () -> T
init(_ builder: @escaping () -> T) {
@IanKeen
IanKeen / AnyPublisher+Extension.swift
Created March 17, 2021 17:02
Extension to create an AnyPublisher to easily 'lift' async code into Combine
extension AnyPublisher where Failure: Error {
struct Subscriber {
fileprivate let send: (Output) -> Void
fileprivate let complete: (Subscribers.Completion<Failure>) -> Void
func send(_ value: Output) { self.send(value) }
func send(completion: Subscribers.Completion<Failure>) { self.complete(completion) }
}
init(_ closure: (Subscriber) -> AnyCancellable) {
@IanKeen
IanKeen / EnvironmentValues.swift
Last active January 5, 2024 08:49
SwiftUI: Peek at/extract hidden environment values
import Foundation
import SwiftUI
extension EnvironmentValues {
public func value<T>(_: T.Type = T.self, forKey key: String) -> T? {
guard let value = first(where: { name($0, equals: key) }) else {
print("No EnvironmentValue with key '\(key)' found.")
return nil
}
@IanKeen
IanKeen / Convertible.swift
Created April 24, 2020 16:57
PropertyWrapper: Convert to/from raw type during decoding/encoding
import Foundation
public protocol CodingStrategy {
associatedtype Converted
associatedtype RawValue: Codable
static func toRaw(_ value: Converted) throws -> RawValue
static func toValue(_ raw: RawValue) throws -> Converted
}
@IanKeen
IanKeen / Partial.swift
Last active November 16, 2023 16:58
Partial<T>
/// A wrapper for a partial representation of a `T`.
/// It can be constructed over time, then later used to
/// build a complete `T`
@dynamicMemberLookup
public struct Partial<T> {
enum Error: Swift.Error {
case invalid(PartialKeyPath<T>)
}
// MARK: - Private Properties
@IanKeen
IanKeen / Example.swift
Created February 7, 2021 03:09
PropertyWrapper: Ignore codable properties
struct Foo: Codable {
var name: String
@Ignore var foo: Int?
}
let model = Foo(name: "Ian", foo: 42)
let data = try! JSONEncoder().encode(model)
print(String(data: data, encoding: .utf8)!) // {"name":"Ian"}
@IanKeen
IanKeen / EntryPoint.swift
Last active August 17, 2023 03:33
Example main.swift
import Foundation
import SwiftUI
let isUITesting = /* your UI test detection here */
@main
struct EntryPoint {
static func main() {
if isUITesting {
UITestApp.main()
@IanKeen
IanKeen / AnyCodable.swift
Last active August 8, 2023 22:02
AnyCodable
public struct AnyCodable: Codable {
public var base: Any
public init(_ base: Any) {
self.base = base
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
guard !container.decodeNil() else {
@IanKeen
IanKeen / Example.swift
Last active August 2, 2023 21:07
ObservableObjectContainer: Consolidate nested/child ObservableObjects into a single publisher, useful for 'parent' ObservableObjects
// Setup
class Child: ObservableObject {
@Published var value = ""
}
class Parent: ObservableObjectContainer {
let single = Child()
let array = [Child(), Child()]
func updateSingle() {
@IanKeen
IanKeen / Example+Object.swift
Last active August 2, 2023 16:39
Simple, highly composable Validator
extension Validator where Input == User, Output == User {
static var validUser: Validator<User, User> {
return .keyPath(\.name, .isNotNil && .isNotEmpty)
}
}
struct User {
let name: String?
}