Skip to content

Instantly share code, notes, and snippets.

View jakehawken's full-sized avatar
🆒

Jake Hawken jakehawken

🆒
View GitHub Profile
extension Array {
func scan(forEachNeighbors action: (Element, Element) -> Void) {
guard count >= 2 else {
return
}
var indexA = 0
var indexB = 1
while indexB <= count - 1 {
// InsetTextField.swift
// Created by Jacob Hawken on 4/2/22.
import UIKit
class InsetTextField: UITextField {
var leftInset: CGFloat = 8 { didSet { setNeedsLayout() } }
var rightInset: CGFloat = 8 { didSet { setNeedsLayout() } }
var topInset: CGFloat = 8 { didSet { setNeedsLayout() } }
@jakehawken
jakehawken / TestablePlaygrounds.swift
Last active June 23, 2023 15:53
Testable Swift Playgrounds! Just drop this in the Sources folder of a Swift Playground, and you'll be able to write XCTest-style tests right there in your code!
/*
Ever wanted to write unit tests in a Swift Playground? … No? Oh.
I’m really the only person? Well ok, then never mind.
If you change your mind though, you can drop this file directly
into the Sources folder and be able to write XCTest-style code
directly in your playground. A proper git repo with a README
file and code examples is on the way.
*/
import Foundation

Jake's Chili

It's not a particularly complicated recipe, but instead it's about the ingredients (e.g. solid rather than ground beef), and taking the time to do little things that will give huge flavor rewards (e.g. roasting your own chiles and convection browning the sauce). The majority of the cook time is fairly hands-off, and the early investment pays dividends in the simmer.

Remember: Chili is a stew, not a soup. It's ok if it's thick.

Prep time: ~30-40 minutes

Cook time: 3-6 hours (depending on preference and dedication)

Ingredients

@jakehawken
jakehawken / ForeEachAdjacent.swift
Created May 18, 2020 20:07
A helper for comparing neighbors in an array
extension Array {
func forEachAdjacent(do block: ((Element, Element))->()) {
guard count > 1 else {
return
}
var secondIndex = 1
while secondIndex < count {
let firstVal = self[secondIndex - 1]
let secndVal = self[secondIndex]
extension String {
func occurrencesOfCharacter(_ character: Character) -> Int {
var count = 0
for char in self {
if char == character {
count += 1
}
}
return count
}

Jake's Sandwich Sourdough Bread

I created this recipe with three main goals in mind, and I'm delighted to say that I've achieved all three.

  1. Mild flavor: This bread is not very sour, despite its natural leavening/fermentation, and thus works well for a wide variety of purposes (my kids and I love using it for PB&J). This is largely due (I believe) to the introduction of fats and sugar early on. The fats coat the flour, slowing the lactic acid-producing bacteria, and making up for that by feeding the yeast some sugar up front.
  2. Fast turnaround time: Unlike other sourdough recipes, you can make your dough and bake it all in the same day (provided you feed your starter the night before).
  3. Functional sandwich bread: Unlike traditional, crusty sourdough, this loaf is tender, soft, and flexible. It's a super versatile sandwich bread, and maintains its freshness/moisture longer than most home-baked bread.

And on top of this, it's super easy and doesn't take much time where you're actually invo

@jakehawken
jakehawken / ViewHierarchy.swift
Last active February 3, 2020 00:38
I'm tired of Chisel crapping the bed. Time to roll a native solution.
extension UIApplication {
static func printAppVCHierarchy() {
shared.printViewControllerHierarchy()
}
func printViewControllerHierarchy() {
guard let rootVC = keyWindow?.rootViewController else {
print("Print failed. No root view controller found.")
return
extension String {
func removingPossibleSuffix(_ suffix: String) -> String {
guard hasSuffix(suffix) else {
return self
}
var segments = components(separatedBy: suffix)
if segments.count > 1 {
segments.removeLast()
return segments.joined(separator: suffix)
@jakehawken
jakehawken / StreamPubSub.swift
Last active February 4, 2020 00:52
StreamPubSub: A bare-bones data stream implementation.
class StreamSubscriber<DataModel, LEEOModel> { //LEEO stands for "loading, empty, error, & offline"
typealias Callback = (State) -> ()
typealias CancelBlock = ()->()
enum State {
case newData(DataModel)
case leeo(LEEOModel)
}
private let callbackList: SinglyLinkedList<Callback>