June 11, 2020

Black Lives Matter

I’ve been meaning to post something online for weeks now. I’ve made excuses for myself. Excuses like “I don’t have a very big following, nothing I say will make a difference”. But that’s fucking bullshit. Every voice matters. The last few days have made me realize that I don’t know close to enough about the struggles of minorities. Of course I am well aware of the structural racism in our world.

Read more...
April 29, 2020

Clicking Background Windows

Here’s a little reminder that by holding down command you can send clicks to a view in the background without the current app losing focus. Handy when a big iPad simulator and Xcode window doesn’t fit side-by-side!

April 25, 2020

I really wish there was some better built in way of building forms in iOS (Catalyst). I know SwiftUI Forms is a thing. But I want to create a “Mac native” form.

I should probably learn AppKit one of these days. But I want to be able to run this app on an iPad as well.

April 25, 2020

Efficient Text Navigation on macOS

A while back I noticed my wife using the trackpad on her MacBook Air to select text and felt this inner little nerd know-it-all poke my brain. And so the idea for this blog post was born. I cannot remember when or how I learned these tricks. Probably as an accident when I was learning HTML as a ten year old, writing all caps tags. Anyway, I’ve been thinking about jotting down these tips for a long time, so here we go.

Read more...
April 24, 2020

I had a peak of interest for SwiftUI a while back. But after that experience I feel like I only want to build “handcrafted artisanal” UIKit apps instead. Getting to 90% is WAY faster with SwiftUI. But getting to insanely great takes another 90% and what feels like a lot of hacky code.

February 2, 2020

Tangerine Habit Tracker

Tangerine is the first habit tracker that I’ve been able to really stick with. It’s a pretty new app but came out of the gates strong. If you’re looking for an app to help you keep on track with all your 2020 resolutions1 I can’t recommend Tangerine enough. I have a few quibbles of course. Like completing a task after midnight breaks your streak. I understand the reasons for this. The developer is aware and is looking to solving this in the future.

Read more...
January 30, 2020

Using Self Executing Closures to Run Code in SwiftUI

Not being able to run arbitrary code in SwiftUI view builders can be quite annoying. The other day I realized it’s possible to use self executing closures to work around this! Here’s a contrived example that creates a stretchy header: struct ScrollThing: View { var body: some View { ScrollView { VStack(spacing: 0) { GeometryReader { g in Color.white .offset(y: { let offsetY = g.frame(in: .global).minY return offsetY > 0 ?

Read more...
December 25, 2019

UICollectionView Ergonomics

One of my favorite things in UIKit is UICollectionView. I love how versatile it is. With iOS 13 it got even better with the diffable data source and compositional layout APIs. However, when dealing with collection views there’s a lot of boiler plate one has to take care of. In this post I want to share some of the code I’ve written to make working with collection views a bit nicer.

Read more...
October 3, 2019

Combine's Sequence Publisher Missing First Element

Just had a fun run in with a bug in Combine. Any Sequence can produce a Publisher that publishes each element in the sequence when you subscribe to it. You might have a custom sequence implementation that counts from 1 to 9: final class Incrementer { var value = 0 func next() -> Int? { value += 1 guard value < 10 else { return nil } return value } } extension Incrementer: Sequence { func makeIterator() -> AnyIterator<Int> { return AnyIterator { self.

Read more...
October 2, 2019

Plantry 3.4: Search

After a brief holiday in 3.3, Search is now back in Plantry and it’s better than ever. Built using SQLite’s FTS4 it enables our users to filter recipes based on ingredients, their name and so on. This is something we’ve been wanting to do a long time, feels great to finally ship. Many thanks to Gwendal RouĂ© for his amazing work on GRDB.swift and the quick responses to issues. I also finally had a use for the quintessential reactive programming example: debouncing search queries!

Read more...