Skip to content

Instantly share code, notes, and snippets.

@ole
ole / XCTExpectation.swift
Last active Jan 21, 2021
A variant of XCTKVOExpectation that works with native Swift key paths. To try it out, paste the code into an Xcode playground and observe the unit test output in the console. See my blog post at https://oleb.net/blog/2018/02/xctkvoexpectation-swift-keypaths/
View XCTExpectation.swift
import XCTest
/// An expectation that is fulfilled when a Key Value Observing (KVO) condition
/// is met. It's variant of `XCTKVOExpectation` with support for native Swift
/// key paths.
final class KVOExpectation: XCTestExpectation {
private var kvoToken: NSKeyValueObservation?
/// Creates an expectation that is fulfilled when a KVO change causes the
/// specified key path of the observed object to have an expected value.
@ole
ole / README.md
Created Aug 7, 2020
Extract a value from the SwiftUI environment by the name of its associated EnvironmentKey (e.g. "ForegroundColorKey").
View README.md

Extract a value from the SwiftUI environment by the name of its associated EnvironmentKey (e.g. "ForegroundColorKey").

Tested only in Xcode 12.0 beta 4 in the iOS simulator. May break in other environments because it uses reflection. If SwiftUI's private type hierarchy changes, it will probably stop working.

@ole
ole / !swiftui-reflection-dump.md
Last active Jan 17, 2021
A dump of the SwiftUI.framework binary for the iOS simulator (as of Xcode 12.0 beta 2) using the swift-reflection-dump tool.
View !swiftui-reflection-dump.md

A dump of the SwiftUI.framework binary for the iOS simulator (as of Xcode 12.0 beta 2) using the swift-reflection-dump tool.

Note: I used a Swift 5.3 compiler build from a few weeks ago that I had laying around. Because of ABI stability, I don't think the swift-reflection-dump version has to match the compiler version that was used to build the binary, but I'm not 100% sure.

@ole
ole / AsyncOperation.swift
Created Aug 19, 2018
An (NS)Operation subclass for async operations
View AsyncOperation.swift
import Foundation
/// An abstract class that makes building simple asynchronous operations easy.
/// Subclasses must override `main()` to perform any work and call `finish()`
/// when they are done. All `NSOperation` work will be handled automatically.
///
/// Source/Inspiration: https://stackoverflow.com/a/48104095/116862 and https://gist.github.com/calebd/93fa347397cec5f88233
open class AsyncOperation: Operation {
public init(name: String? = nil) {
super.init()
@ole
ole / UIAlertController+TextField.swift
Last active Nov 15, 2020
A UIAlertController with a text field and the ability to perform validation on the text the user has entered while the alert is on screen. The OK button is only enabled when the entered text passes validation. More info: https://oleb.net/2018/uialertcontroller-textfield/
View UIAlertController+TextField.swift
import UIKit
/// A validation rule for text input.
public enum TextValidationRule {
/// Any input is valid, including an empty string.
case noRestriction
/// The input must not be empty.
case nonEmpty
/// The enitre input must match a regular expression. A matching substring is not enough.
case regularExpression(NSRegularExpression)
@ole
ole / core-data-backup.swift
Last active Nov 5, 2020
How to make a copy of a Core Data SQLite database. See https://oleb.net/blog/2018/03/core-data-sqlite-backup/ for more.
View core-data-backup.swift
import CoreData
import Foundation
/// Safely copies the specified `NSPersistentStore` to a temporary file.
/// Useful for backups.
///
/// - Parameter index: The index of the persistent store in the coordinator's
/// `persistentStores` array. Passing an index that doesn't exist will trap.
///
/// - Returns: The URL of the backup file, wrapped in a TemporaryFile instance
@ole
ole / date-format-strings.swift
Last active Oct 8, 2020
Type-safe date format strings using string interpolation. Requires Swift 5.0.
View date-format-strings.swift
// Type-safe date format strings using string interpolation
// Requires Swift 5.0.
import Foundation
enum DateFormatComponent {
case era(AlphaStyle)
case year(MinimumDigits)
case yearForWeekOfYear(MinimumDigits)
case quarter(AlphaNumericStyle)
View TypedHeterogeneousDictionaries.swift
/*:
Joe Groff:
> In a lot of the ways people use dictionaries/maps/hashtables, there's a type dependency between
> the keys and values, but most mainstream typed languages provide homogeneously-typed maps.
> Are there any that try to preserve more interesting type relationships between key and value?
> https://twitter.com/jckarter/status/1278739951568314368
> As one example, it's common for specific keys to be associated with specific types, like in
> {"name": "Tanzy", "age": 13}, "name" should always map to a string, and "age" to a number.
@ole
ole / KeyedContainer.swift
Created Dec 10, 2019
A property wrapper for dictionaries with keys that are raw-representable as strings. It modifies the wrapped dictionary's encoding/decoding behavior such that the dictionary is encoded as a dictionary (unkeyed container) rather than as an array (keyed container). For context, see https://oleb.net/blog/2017/12/dictionary-codable-array/
View KeyedContainer.swift
import Foundation
// MARK: - KeyedContainer
/// A property wrapper for dictionaries with keys that are raw-representable as strings.
/// It modifies the wrapped dictionary's encoding/decoding behavior such that the dictionary
/// is encoded as a dictionary (unkeyed container) rather than as an array (keyed container).
///
/// For context, see <https://oleb.net/blog/2017/12/dictionary-codable-array/>.
@propertyWrapper
@ole
ole / Mojave-dynamic-wallpaper-notes.md
Last active Jul 15, 2020
Reverse-engineering the dynamic wallpaper file format in macOS Mojave.
View Mojave-dynamic-wallpaper-notes.md

The dynamic wallpaper in MacOS Mojave is a single 114 MB .heic file that seems to contain 16 embedded images.

It also contains the following binary plist data in its metadata under the key "Solar". It's an array of 16 items, each with four keys:

  • i (integer). This seems to be the image index.
  • o (integer). This is always 1 or 0. Stephen Radford thinks it indicates dark mode (0) vs. light mode (1).
  • a (decimal). I’m pretty sure this is the angle of the sun over the horizon. 0º = sunset/sunrise. 90º = sun directly overhead. Negative values = sun below horizon.
  • z (decimal). This seems to be the cardinal position of the sun relative to the camera. 0º = sun is directly in front of the camera. 90º = sun is directly to the right of the camera. 180º = sun is directly behind the camera.