Skip to content

Instantly share code, notes, and snippets.

Ian Keen IanKeen

Block or report user

Report or block IanKeen

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@IanKeen
IanKeen / Decodable+Empty.swift
Created Jan 23, 2020
Custom Decoder that can be used to create empty Decodable instances
View Decodable+Empty.swift
import Foundation
extension Decodable {
public static func empty() throws -> Self {
return try Self(from: EmptyDecoder())
}
}
private class EmptyDecoder: Decoder {
let codingPath: [CodingKey] = []
@IanKeen
IanKeen / Derived.swift
Created Nov 6, 2019
PropertyWrapper for creating derived properties
View Derived.swift
@propertyWrapper
struct Derived<Value> {
var wrappedValue: Value {
get { fatalError() }
set { fatalError() }
}
private let getter: (Any) -> Value
private let setter: (Any, Value) -> Void
@IanKeen
IanKeen / Redraw.swift
Created Nov 5, 2019
PropertyWrapper to automatically redraw UIViews when a value changes
View Redraw.swift
@propertyWrapper
struct Redraw<Value> {
var wrappedValue: Value
init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
static subscript<Instance: UIView>(
_enclosingInstance instance: Instance,
@IanKeen
IanKeen / GivenWhenThen.swift
Last active Feb 14, 2020
FunctionBuilder mvp for a given/when/then test setup
View GivenWhenThen.swift
import XCTest
@_functionBuilder
struct Test<T> {
var data: T
var given: given<T>
var when: when<T>
var then: then<T>
func execute() {
@IanKeen
IanKeen / KeyPathAccessible.swift
Last active Jun 24, 2019
Naive KeyPath code for dictionaries and arrays
View KeyPathAccessible.swift
public protocol KeyPathComponent { }
extension String: KeyPathComponent { }
extension Int: KeyPathComponent { }
public protocol KeyPathAccessible {
func value<T>(at component: KeyPathComponent) -> T?
}
extension KeyPathAccessible {
@IanKeen
IanKeen / CollectionView.swift
Last active Jun 21, 2019
Playing with Swift UI to see if it's possible to build a 'CollectionView' type thing
View CollectionView.swift
import SwiftUI
extension Array {
func chunk(size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
return Array(self[$0..<Swift.min($0 + size, count)])
}
}
}
@IanKeen
IanKeen / TestView.swift
Created Jun 5, 2019
UITextView with some commonly needed additions
View TestView.swift
import UIKit
open class TextView: UITextView {
// MARK: - Public Properties
public var autoSizing: Bool = false {
didSet { redraw() }
}
public var minimumLines: Int = 1 {
didSet { redraw() }
}
@IanKeen
IanKeen / Value.swift
Last active Jun 25, 2019
Brute force generic Codable value that lets you work in 1 type while maintaining the raw type
View Value.swift
public typealias LosslessStringCodable = LosslessStringConvertible & Codable
public struct Value<T: LosslessStringCodable>: Codable {
private let type: LosslessStringCodable.Type
public var value: T
public init(from decoder: Decoder) throws {
do {
self.value = try T.init(from: decoder)
@IanKeen
IanKeen / Decodable+Enums.swift
Created Apr 18, 2019
DSL for brute force enum decoding
View Decodable+Enums.swift
public struct DecodingRoutine<T: Decodable> {
let decode: (Decoder) throws -> T?
}
extension DecodingRoutine {
public static func `default`(_ value: T) -> DecodingRoutine {
return .init { _ in value }
}
}
View DictionaryDecoder.swift
import Foundation
class DictionaryDecoder {
init() { }
func decode<T: Decodable>(_ type: T.Type, from data: [String: Any]) throws -> T {
let decoder = _Decoder(codingPath: [], source: data)
return try T(from: decoder)
}
}
You can’t perform that action at this time.