Skip to content

Instantly share code, notes, and snippets.

View drewmccormack's full-sized avatar

Drew McCormack drewmccormack

View GitHub Profile
@drewmccormack
drewmccormack / SerialMacro.swift
Created July 26, 2024 11:49
A macro that can be applied to an async func to generate a peer func (serial_<funcname>) that uses an internal queue to serialize execution. That is, it guarantees that only one copy of the func will run at a time. (Note that this can deadlock if it reenters.)
import SwiftSyntax
import SwiftSyntaxMacros
import SwiftCompilerPlugin
public enum SerialError: Error, CustomStringConvertible {
case invalidInput
case invalidOutput
public var description: String {
switch self {
@drewmccormack
drewmccormack / AsyncSerialQueue.swift
Last active July 24, 2024 17:17
Proof of concept for a serializing queue for async funcs in Swift. It orders the calls, but also ensures each call is executed to completion before the next starts, thus avoiding interleaving races which can arise in multiple calls to an async func.
/// A queue that executes async functions in order, and atomically.
/// That is, each enqueued func executes fully before the next one is started.
struct AsyncSerialQueue {
typealias Block = () async throws -> [Int]
private struct Item {
let block: Block
let continuation: CheckedContinuation<[Int], Error>
}
@drewmccormack
drewmccormack / LetTheCoWGo.swift
Created February 2, 2019 10:25
Demonstrates how a Swift value constant can mutate when using Copy-on-Write (CoW) and multi-threading.
import Foundation
struct NuclearPowerStationOperator {
class Storage {
var turnOffCores: Bool = false
func copy() -> Storage {
let new = Storage()
new.turnOffCores = turnOffCores
return new
@drewmccormack
drewmccormack / UpdateLocalizations.swift
Last active September 26, 2023 08:36
Using the AppStoreConnect_Swift_SDK package to update localizations on App Store Connect.
import AppStoreConnect_Swift_SDK
func updateMetadata(forBundleID bundleID: String) async throws {
let configuration = try! APIConfiguration(issuerID: "...", privateKeyID: "...", privateKey: "...")
let provider = APIProvider(configuration: configuration)
// Get app
let appRequest = APIEndpoint.v1
.apps
.get(parameters: .init(filterBundleID: [bundleID], include: [.appInfos, .appStoreVersions]))
@drewmccormack
drewmccormack / SendFile.scpt
Created July 4, 2016 17:41
Javascript (JXA) script to send attached files one per email
// Open in Script Editor, and Export as an Application
// To use, drag files from folder onto Droplet
function openDocuments(docs) {
var mail = Application("Mail")
for (var i = 0; i < docs.length; i++) {
var doc = docs[i].toString()
var filename = doc.replace(/^.*[\\\/]/, '')
@drewmccormack
drewmccormack / symbolicate-sample-dump.py
Last active August 15, 2023 09:32
Symbolicates a sample dump from Activity Monitor
#!/usr/bin/env python
#
# To use this, just put the DSYMS in the same directory as the sample dump file,
# and run the script from that directory, passing the sample dump file name as only argument
#
import re, sys, os, subprocess
sampleFile = sys.argv[1]
@drewmccormack
drewmccormack / Queue.swift
Created September 29, 2022 07:02
A Queue (FIFO) built from an actor.
actor Queue {
private var tasks: [() async -> Void] = []
func enqueue(_ task: @escaping () async -> Void) {
tasks.append(task)
Task { await runNext() }
}
private func runNext() async {
guard !tasks.isEmpty else { return }
@drewmccormack
drewmccormack / NSString+MCHTMLToPlainTextConversion.h
Created October 5, 2012 14:29
Convert a NSString with HTML into a plain text string using NSXMLParser.
#import <Foundation/Foundation.h>
@interface NSString (MCHTMLToPlainTextConversion)
-(NSString *)stringByConvertingHTMLToPlainText;
@end
@drewmccormack
drewmccormack / LabelUniqueSet.swift
Created August 10, 2021 09:33
Introduces a Set type that stores enums, including those with associated types, and uniques on the label rather than the value.
struct Label: Hashable {
var label: String
}
protocol LabelUniquing {
var label: Label { get }
}
extension LabelUniquing {
//
// Lightweight but powerful state machine.
//
// Usage:
// enum TrafficLight: State {
// case red, orange, green
// }
//
// var trafficLights = StateMachine<TrafficLight>(initialState: .red)
// trafficLights.addRoute(from: .red, to: .green)