Skip to content

Instantly share code, notes, and snippets.

View timshadel's full-sized avatar

Tim Shadel timshadel

View GitHub Profile
infix operator !! { associativity left precedence 160 }
@inline(__always) public func !!<T>(value: T?, @autoclosure die: () -> Void) -> T {
guard let value = value else {
die()
exit(-1)
}
return value
}
let test: String? = nil
@timshadel
timshadel / APNG.swift
Created August 1, 2016 21:21
Programmatically create APNG files
// By Heber Sheffield
public class func save(animatedImageSequence images: Array<CGImage>, withFrameDelay delay: CGFloat, numberOfLoops: Int, to url: URL) {
let fileProperties = [kCGImagePropertyPNGDictionary as String: [kCGImagePropertyAPNGLoopCount as String: numberOfLoops]]
let frameProperties = [kCGImagePropertyPNGDictionary as String: [kCGImagePropertyAPNGDelayTime as String: delay]]
guard let destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, images.count, nil) else { fatalError("couldn't create image destination for url: \(url)") }
CGImageDestinationSetProperties(destination, fileProperties)
for image in images {
CGImageDestinationAddImage(destination, image, frameProperties)
}
@timshadel
timshadel / XXXX-enum-case-blocks.md
Last active January 13, 2017 02:07
Draft of Swift Evolution Proposal for Case Blocks

Enum Case Blocks

  • Proposal: SE-XXXX
  • Authors: Tim Shadel
  • Review Manager: TBD
  • Status: TBD

Motivation

Add an optional syntax to declare all code related to a single case in one spot. For complex enums, this makes it easier to ensure that all the pieces mesh coherently across that one case, and to review all logic associated with a single case. This syntax is frequently more verbose in order to achieve a more coherent code structure, so its use will be most valuable in complex enums.

@timshadel
timshadel / toc.rb
Created January 28, 2017 03:28
Generate TOC for Github markdown docs
#!/usr/bin/env ruby
# Generate a correct table of contents for Github markdown documents
# See https://gist.github.com/asabaylus/3071099#gistcomment-1593627
doc = IO.readlines(ARGV[0])
lines = doc.select { |l| l.start_with? "#" }.map do |l|
indent = l.chomp.gsub(/^# .*/, '* ').gsub(/^## .*/, ' * ').gsub(/^### .*/, ' * ')
link = l.gsub(/[^a-zA-Z\- ]/u,'').strip().downcase.gsub(' ','-')
indent + l.chomp.gsub(/^([\# ]*)(.*)$/, '[\2]') + "(##{link})"
@timshadel
timshadel / SafeArray.swift
Created May 15, 2017 22:58
A start of thread safe access to an array.
struct SafeArray<Element> {
private let multiReaderQueue: DispatchQueue
private var array = [Element]()
init() {
multiReaderQueue = DispatchQueue(label: "safeArray.internal", attributes: .concurrent)
}
var count: Int { return read { self.array.count } }
@timshadel
timshadel / version.sh
Last active August 18, 2017 16:28
iOS automatic version script
#!/bin/sh
###
# Version: $Major.$Minor.$Commit
#
# How it works:
# 1. To roll minor number, tag each App Store release with a message.
# 2. To roll major number, create an additional tag on the last App Store
# release (e.g. "2.17.9") with new major number (e.g. "3").
# 3. `Release` builds require a clean working directory.
@timshadel
timshadel / Matchers.swift
Created February 16, 2019 20:23
XCTest custom matchers
//
// XCTestCase+Matchers.swift
// greatwork
//
// Created by Tim on 4/14/17.
// Copyright © 2017 OC Tanner Company, Inc. All rights reserved.
//
import Foundation
import XCTest
import Marshal