Skip to content

Instantly share code, notes, and snippets.

extension RawRepresentable where RawValue: Numeric {
/// Returns all the values of a RawRepresentable whose RawValue is Numeric. This static property expressly exists
/// for enumerations, though can be used elsewhere. Works only for contiguous values.
/// Supposing we have:
/// ```
/// enum Counter {
/// case one, two
/// }
/// ```
/// then `Counter.allValues == [.one, .two]`.
extension Collection where Iterator.Element: Equatable {
/// Computes the indices of different elements between two collections. This is useful for updating table views
/// with row deletions and insertion
/// - Parameter other: the collection to compute the index difference
/// - Returns: a tuple with indices to delete and insert on `self` to create a collection equivalent to `other`
/// - Discussion: This algorithm does not work for collections with duplicate elements.
public func indexDifference(with other: Self) -> (deleted: [Index], inserted: [Index]) {
var (deleted, inserted): ([Index], [Index]) = ([], [])
@jakebromberg
jakebromberg / Disposable.swift
Created October 14, 2017 20:47
Encapsulates the steps necessary to tear down some unit of work, typically an asynchronous operation like a network task.
import Foundation
/// `Disposable` encapsulates the steps necessary to tear down some unit of work, typically an asynchronous operation
/// like a network task.
public protocol Disposable {
/// Disposes the object. This may be invoked multiple times, but only performs its side-effects once.
func dispose()
}
extension URLSessionTask: Disposable {
@jakebromberg
jakebromberg / AVAssetTrim.swift
Last active August 16, 2024 15:41 — forked from acj/TrimVideo.swift
Trim video using AVFoundation in Swift
import AVFoundation
import Foundation
extension FileManager {
func removeFileIfNecessary(at url: URL) throws {
guard fileExists(atPath: url.path) else {
return
}
do {
@jakebromberg
jakebromberg / PlayerLoader.swift
Created October 3, 2017 03:38
Takes out some of the pain from loading an AVPlayer object.
import AVFoundation
/// The `PlayerLoader` class provides a callback mechanism for consumers of `AVPlayer` when loading a resource.
/// AVFoundation works by an inconvenient series of APIs that rely on KVO for asynchronous operations. This class
/// eliminates the boilerplate that KVO imposes and makes the callsite much more clean.
public final class PlayerLoader: NSObject {
public typealias Callback = (AVPlayer) -> ()
/// The callback will initialize to a non-nil value. The callback is set to nil once it's invoked, at which time the
/// KVO observation is removed. This is necessary to avoid double-removing the KVO observation.
import CoreLocation
extension CLLocation {
public static func +(lhs: CLLocation, rhs: CLLocation) -> CLLocation {
let summedLat = lhs.coordinate.latitude + rhs.coordinate.latitude
let summedLong = lhs.coordinate.longitude + rhs.coordinate.longitude
return CLLocation(latitude: summedLat, longitude: summedLong)
}
public static func /(lhs: CLLocation, rhs: Double) -> CLLocation {
final class ReadOnly<T> {
private let value: T
init(_ value: T) {
self.value = value
}
subscript<U>(keyPath: KeyPath<T, U>) -> U {
return self.value[keyPath: keyPath]
}
extension Sequence where Element: Hashable {
func frequencies() -> [Element : Int] {
return Dictionary(map { ($0, 1) }, uniquingKeysWith: { $0 + $1 })
}
}
assert("hello".frequencies() == ["e": 1, "o": 1, "l": 2, "h": 1])
@jakebromberg
jakebromberg / EnumeratingOptionSets.swift
Created August 29, 2017 00:02
Lets you represent OptionSets in an enumerable form since OptionSets are not Sequences. Don't try this at home.
extension OptionSet where RawValue: BinaryInteger, RawValue.Stride: SignedInteger {
func splitBitwise() -> [Self] {
let radix: [RawValue] = (0..<RawValue(0.bitWidth)).map { 1 << $0 }
let bitwiseRadices: [RawValue] = radix.map { self.rawValue & $0 }
let nonzeroBitwiseRadices: [RawValue] = bitwiseRadices.filter { $0 != 0 }
let result: [Self] = nonzeroBitwiseRadices.map { Self(rawValue: $0) }
return result
}
}
extension Collection {
/// Splits a collection into its first element and a SubSequence of the rest of its elements.
func split() -> (head: Element, tail: SubSequence)? {
guard let first = first else {
return nil
}
return (first, dropFirst())
}