RSSAmplifier

Blog

Scott Berrevoets

scottberrevoets.comRSS feed ↗39 posts

Latest posts

The foundations of a mobile platform

In larger teams or companies, most people agree that the mobile platform is the shared infrastructure an app and its features are built upon. In earlier stages, that might simply mean "shared code and helper functions", but when the app and team start scaling, the platform deserves a lot more …

Liquid Glass can be gradually rolled out

By default, Liquid Glass is enabled for apps that are built with Xcode 26. For any Xcode 26 version, Apple has provided the UIDesignRequiresCompatibility Info.plist key to opt out of Liquid Glass. However, Info.plist values are impossible to either partially enable or gradually roll out. But today someone …

How GitHub handles Git LFS

Snapshot tests have become an increasingly popular tool for mobile teams to verify UI changes, but one question all teams run into is: where do we store hundreds if not thousands of PNG files? Git Large File Storage (LFS) is one of the more common ways to do this for …

ZeroVer is a (realistic) SemVer parody

Software whose author has big ideas they want to implement before committing to a Semantic Versioning (or SemVer) versioning methodology often starts with many 0.x releases before ever reaching a 1.0 version. The 0.12.2 release of neovim led me to ZeroVer , which details and explains this …

Objective-C enums can be string-backed... sort of

While looking at AVAudioSessionErrorCode in Xcode, I noticed something interesting in its definition: typedef CF_ENUM ( AVAudioInteger , AVAudioSessionErrorCode ) { AVAudioSessionErrorCodeNone = 0 , AVAudioSessionErrorCodeMediaServicesFailed = ' msrv ' , // 0x6D737276, 1836282486 AVAudioSessionErrorCodeIsBusy = ' ! act ' , // 0x21616374, 560030580 AVAudioSessionErrorCodeIncompatibleCategory = ' !…

Swift's Optional has a take() function

After the introduction of Optional.toggle() back in 2018, I thought I had learned everything there is to Optional , but today I learned about another method: Optional.take() . As the documentation points out, it returns the value of a mutable optional (if not nil ) and then resets the variable to …

Claude can load files "lazily" or "greedily"

Typically, markdown files can referenced other files by linking to them: [My File](myfile.md) . Claude understands this syntax, making it a nicely portable way to reference files. When prompting in Claude Code, referencing other files works through the @-syntax: @path/to/file . This loads the file into Claude's context …

Review your own AI-generated code

Years ago, when we started to have 5+ contributors to our codebase at Lyft, we had to establish a code review process with high enough value to justify the friction it caused. However, "value" is very subjective, as not everyone cares about the same qualities of a pull request: Catching …

All in on Interface Builder: 10 years later

Back in 2017, I wrote about how we used Interface Builder as our primary way of building UI at Lyft. Interestingly, Speak chose to use Interface Builder to build UI too before SwiftUI came along, though without the same tooling we had at Lyft. With Interface Builder mostly forgotten, including …

macOS can remember SSH passphrases

Having to type out my password every time in SSH into a machine got a little tedious for me. Turns out macOS can save these passphrases to the Keychain to save some typing each time you try to connect to a host over SSH. To enable this, make sure you're …

Scaling my git/tmux workflows for AI agents

After I started to ramp up on agentic coding, I found my workflow lagging behind how I ended up working. Previously I would clone my project's repo twice and switch back and forth between the clones. I used stack-based git workflow git-pile , which eliminated the overhead of switching branches and …

git can tell you ignored files, and why

Today I created a new file at ./Resources/Environment.xcconfig , but git didn't pick up on the file and didn't show it in git status . I suspected the file was gitignored, but nothing in my .gitignore was obviously excluding this file. git status --ignored adds a section in to the …

There is a term for words like i18n and a11y

They're called numeronyms and they're common terms in tech to refer to long words like "internationalization" (i18n) and accessibility (a11y). However, they're also used outside of tech: K9, 24/7, and gr8 are all numeronyms as well. The official definition, according to Wikipedia : A numeronym is a word, usually an …

Localization troubles with Swift PM

A few weeks ago we got bit by a piece of Apple magic in its localization workflow when combined with Swift PM. The problem we ran into was that as soon as we moved all our Localizable.strings files to an SPM package, none of the localizations would be picked …

Managing code deprecations on iOS

A great manager I once worked with had been at Google for a while and poked fun at an aspect of its engineering culture: any given service was either deprecated or not yet ready for adoption. I spend a lot of my time working on mobile platform development and over …

Flywheel of tech debt

Tech debt is often compared to financial debt, in that you're borrowing development time now to pay it off with more development time later. When "later" comes around, the development time needed to fix the issues introduced earlier is too high so the new thing is also not built "correctly …

Art of the state

@State plays a prominent role in any SwiftUI app, and for good reason: app state is what ultimately drives the UI and how the user interacts with your app. This has always been true, but SwiftUI embraces this reality with specific APIs and a unidirectional data flow. UIKit-based apps or …

Composing a resume in markdown

I recently updated my resume, and after a few iterations of tweaking the same Pages file I started more than a decade ago, I decided that I really wanted source control to make it easier to keep track of changes and to have different versions of the same resume. Additionally …

Incremental complexity in iOS development

I wrote my first app, a map to navigate my college campus, in the winter of 2011, on iOS 4.x and with Xcode 4.x. There were 25 frameworks, iOS 7 hadn't been invented yet, there was only 1 phone size, and we wrote apps with Objective-C. But things …

Looking up words in a dictionary with Neovim

When writing code in neovim, I frequently use K to look up documentation, function signatures, variable definitions, etc. In markdown files that doesn't make too much sense, but I wanted to use it to look up words in the dictionary instead. This didn't appear to be possible out of the …

Shifting the testing culture: Code coverage

Note This is the third post in a series on shifting our testing culture. Motivation Infrastructure Code coverage Most people will say that code coverage is a measure of how well-tested your code is. I prefer to say it's a measure of how untested a codebase is. Take this example …

Shifting the testing culture: Infrastructure

Note This is the second post in a series on shifting our testing culture. Motivation Infrastructure Code coverage This second article goes a bit deeper into the testing infrastructure we built over the years to optimize the ergonomics and developer experience as much as possible. Our initial test suites only …

Shifting the testing culture: Motivation

Five years ago I began promoting automated testing heavily within Lyft even though I didn't have any real experience in writing big test suites myself. Many hands make light work, so I found a few people who shared this thinking and we started on what turned out a multi-year testing …

Migration strategies in large codebases

Code migrations are a fact of life for large codebases. New technologies pop up, platforms see improvements, and programming languages get new features you might want to adopt. Not performing these migrations and keeping up with the times is simply not an option in most cases. While some migrations are …

Human factors in choosing technologies

I recently saw a thread where someone wanted to introduce a more capable architecture pattern than what most apps start out with in a small team, but received some pushback from teammates and was looking for help in countering their arguments. The thread for the most part focused on the …

Third-party libraries are no party at all

What better way to end the week than with a hot take? In my 8 years at Lyft, product managers or engineers have often wanted to add third-party libraries to one of our apps. Sometimes it’s necessary to integrate with a specific vendor (like PayPal), sometimes it’s to …

iOS Architecture at Lyft

June 30, 2014 was my first day at Lyft as the first iOS hire on the ~3 person team. The app was written in Objective-C, and the architecture was a 5000-line nested switch statement. Since then, the team has grown to about 70 people and the codebase to 1.5M …

Re-binding self: the debugger's break(ing) point

Update 07-29-2019: The bug described below is fixed in Xcode 11 so this blog post has become irrelevant. I'm leaving it up for historical purposes. For the Objective-C veterans in the audience, the strong-self-weak-self dance is a practice mastered early on and one that is used very frequently. There are …

Using Interface Builder at Lyft

Last week people realized that Xcode 8.3 by default uses storyboards in new projects without a checkbox to turn this off. This of course sparked the Interface Builder vs. programmatic UI discussion again, so I wanted to give some insight in our experience using Interface Builder in building the …

Keeping the Lyft iOS App Accessible

Note This article was written by me but originally published on the Lyft Engineering Blog . At Lyft we’re in a unique position: every day we work on an app that affects people in the real, physical world — not just the digital one. This has an especially large impact on …

Silencing NSLog

When your app has a lot of third-party dependencies, what often happens is that those libraries log a bunch of things to the Xcode console to help their own debugging. Unfortunately, a lot of these logs are useful only to the developers of the library, but not the developers of …

Outlets: strong! or weak?

There are a lot of styles out there when it comes to using Interface Builder outlets in Swift. Even Apple's documentation and sample code isn't always consistent. The most common one, the one Apple uses in its sample code, follows this pattern: @IBOutlet private weak var someLabel: UILabel! Let's break …

@objc class prefixes fixed in Xcode 7 beta 4

Back in December I wrote about what I thought was a bug in the Swift compiler that would expose the wrong class name for a Swift class in Objective-C. I then later found out everything worked as intended and I had just misunderstood what @objc() exactly did. Apparently it was …

The power of UIStackView

I was in the audience for "Implementing UI Designs in Interface Builder" at WWDC, where Apple touted UIStackView as a new, better way to lay out your views that in a lot of cases didn't require Auto Layout. While the presentation looked good, I wasn't quite sure this solved a …

@objc creates a wrong class name in Objective-C

A few months ago, I decided I'd get started porting SDCAlertView to Swift, but I was only a few minutes in until I ran into a problem I had no idea how to solve: I couldn't get my class names right in both Swift and Objective-C. Even though there are …

Dev-only iPhones

With today's release of iOS 8.1, most app developers are looking at 4 significantly different iOS versions they will be supporting: iOS 7.0, iOS 7.1, iOS 8.0, and iOS 8.1. Factoring in the number of devices (iPhone 4S, iPhone 5, iPhone 5s, iPhone 6, and …

UIMenuController and the responder chain

The responder chain is a very important paradigm in the world of iOS development, and not terribly hard to understand. Dozens of articles have been written about it, and with some examples, the concept of finding a responder to a certain event by traversing a chain of potential responders is …

Xcode & Objective-C Oddities

Any developer that has worked with Xcode to write a little more than just "Hello, World" knows that Xcode and Objective-C have their quirks. Chances are you have heard of @TextFromXcode , the Twitter handle that portrays Xcode as a high school bully in fake text conversations like this: But it's …

Objective-C prefixes: a thing of the past?

This past week, there was, again, a lot to do about Objective-C and prefixing. To most iOS developers, the story sounds familiar: one camp is strongly in favor, another camps is strongly against, and a third camp couldn't really care less. Unless I'm unaware of any other platforms where the …