Skip to content

Instantly share code, notes, and snippets.

View AllowDecodeFailure.swift
import Foundation
/// Allows a property to fail decoding, defaulting to nil instead of surfacing the error.
@propertyWrapper
struct AllowDecodeFailure<Wrapped>: Codable where Wrapped: Codable {
var wrappedValue: Wrapped?
init() {
self.wrappedValue = nil
}
@davbeck
davbeck / IfElseTernary.swift
Created Oct 22, 2019
Use if/else logic instead of a ternary operator in Swift. Don't do this.
View IfElseTernary.swift
func _if<T>(_ test: Bool, action: () -> T) -> T? {
if test {
return action()
} else {
return nil
}
}
extension Optional {
func _else(action: () -> Wrapped) -> Wrapped {
View Collection+Average.swift
extension Collection where Element: FloatingPoint {
func average() -> Element {
return self.reduce(Element.zero, +) / Element(self.count)
}
}
extension Collection where Element: BinaryInteger {
func average() -> Double {
return Double(self.reduce(0, +)) / Double(self.count)
}
@davbeck
davbeck / Example.swift
Created Sep 10, 2019
RateLimiter.swift
View Example.swift
import PlaygroundSupport
let limiter = RateLimiter(timeframe: 5)
PlaygroundPage.current.needsIndefiniteExecution = true
for i in 0..<100 {
limiter.perform {
print("perform", i)
}
View ParentUpdate.swift
struct Parent: View {
@State var count: Int = 0
var body: some View {
return VStack {
ImageLoadingView(url: URL(string: "https://github.com/recurser/exif-orientation-examples/blob/9c4ccfaea6bfd434ac1c4bb0750ac6fc5848a5f4/Landscape_8.jpg?raw=true")!)
Text("counter: \(count)")
}
.onAppear {
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { (timer) in
self.count += 1
@davbeck
davbeck / DisplayLink.swift
Created Jul 20, 2019
A Combine Publisher version of CADisplayLink.
View DisplayLink.swift
View ReferenceCache.swift
/// The result of a binary search.
struct BinarySearchResult<Index> {
/// The index for the searched key.
///
/// Use this to either insert new values while maintaining the sort order of the collection, or to lookup the value if `isPresent` is true.
var index: Index
/// Whether the key was found in the collection.
///
/// When performing a binary search, even if the value is not found in the collection, an index is returned which can be used to insert a new item at the correct location.
View BinarySearch.swift
// adapted from https://github.com/raywenderlich/swift-algorithm-club/tree/master/Binary%20Search
/// The result of a binary search.
struct BinarySearchResult<Index> {
/// The index for the searched key.
///
/// Use this to either insert new values while maintaining the sort order of the collection, or to lookup the value if `isPresent` is true.
var index: Index
/// Whether the key was found in the collection.
@davbeck
davbeck / README.md
Created Jun 19, 2019
A wrapper for UICollectionViewDiffableDataSource that also handles updates to data
View README.md

UICollectionViewDiffableDataSource does an excellent job of handling changes to data and updating the items accordingly. However, there seems to be no good way to handle updates to existing items. If you follow the samples that Apple provides and define Equatable and Hashable to use an id instead of the complete models value, value changes won't cause the collection view to update those cells. If you leave Equatable as it should be and have it compare all values of a model, the cell will update, but it will completely replace the old cell, causing an undesirable "flash".

UICollectionViewComparableDataSource wraps a UICollectionViewDiffableDataSource and will check for items that have been updated, but not removed or added.

This allows us to make updates to a cell without completely reloading it. This is especially usefull if your cells have some sort of temporary state.

This is just an expirement. Use at your own risk.

View SQLite.swift
import Foundation
import SQLite3
public enum SQLiteError: Error, LocalizedError {
case sqlite(code: Int32, message: String?)
case invalidDatabase
case invalidStatement
case invalidUTF8String