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 / 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)
}
}
@IanKeen
IanKeen / AnyCodingKey.swift
Created Mar 1, 2019
AnyCodingKey: Helpful for a range of Codable tricks
View AnyCodingKey.swift
struct AnyCodingKey: CodingKey {
var stringValue: String
var intValue: Int?
init?(intValue: Int) {
self.intValue = intValue
self.stringValue = "\(intValue)"
}
init?(stringValue: String) {
self.intValue = nil
@IanKeen
IanKeen / CodablePrimitive.swift
Created Mar 1, 2019
CodablePrimitives; Allows for easier handling of types for custom en/de-coders in certain situations
View CodablePrimitive.swift
protocol CodablePrimitive { }
extension String: CodablePrimitive { }
extension Bool: CodablePrimitive { }
extension Double: CodablePrimitive { }
extension Float: CodablePrimitive { }
extension Int: CodablePrimitive { }
extension Int8: CodablePrimitive { }
extension Int16: CodablePrimitive { }
extension Int32: CodablePrimitive { }
@IanKeen
IanKeen / Example.swift
Last active Mar 1, 2019
Composing flat properties onto existing Codable values
View Example.swift
struct WithSecret<T> {
let secret: String
let value: T
}
extension WithSecret: Decodable where T: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: AnyCodingKey.self)
self.secret = try container.decode(String.self, forKey: "secret")
@IanKeen
IanKeen / DictionaryEncoder.swift
Last active Mar 7, 2019
DictionaryEncoder for Encodable types
View DictionaryEncoder.swift
class DictionaryEncoder {
init() { }
func encode(_ value: Encodable) throws -> [String: Any] {
let encoder = _Encoder(codingPath: [])
try value.encode(to: encoder)
guard let result = encoder.value as? [String: Any] else {
throw EncodingError.invalidValue(encoder.value as Any, .init(codingPath: [], debugDescription: "Invalid root container"))
}
You can’t perform that action at this time.