A few months ago, I shared my notes and resources for learning about compilers and LLVM. It turned out to be pretty popular and folks seemed to find it useful. So I decided to do it again, but this time for SwiftUI. However, unlike learning about compilers and LLVM, I am not declaring bankruptcy with learning SwiftUI. While I have still not written a single line of SwiftUI code, I know I eventually will.
Updated: 06 Apr 2021
One aspect of using OmniFocus involves maintaining an archive of your data (if you choose). Over time — think years of using OmniFocus as your main task management tool — your local database of projects and tasks will grow very large, because OmniFocus keeps a record of everything you have completed or dropped. You can think of it as archiving your emails instead of putting them in the trash.
Over the past few years, Apple seems increasingly willing to cooperate with authoritarian governments, uninterested in protecting its own users, and unwilling to actually standup for human rights in broad terms, as often portrayed by its marketing department or direct statements from CEO Tim Cook.
Updated: 24 Mar 2021
Lately, it feels like every few days someone is sharing a new Xcode tip on Twitter or on their blog. They range from hidden settings to features I simply never knew about. I started saving links and planned to add a new “Xcode tips” section to my TIL repo on GitHub to reference later. But as I started, I realized that the resulting markdown file would not be easily discoverable or shareable. I thought, wouldn’t it be nice if the iOS and macOS developer community had a single place to find and share Xcode tips?
Updated: 06 Apr 2021
As I continue to pursue Mac app development more seriously, I can build on and borrow from my many years of iOS experience. While many aspects of writing Mac apps are very similar to iOS, or at least somewhat familiar, other aspects are quite different. One of the big differences is testing, and deciding how many versions of macOS to support.
Updated: 22 Mar 2021
I have a few Swift scripts to automate tedious tasks for maintaining my blog. I updated one today to use pipes. It took me a minute to figure out, because it did not feel very intuitive. I’m not sure if I feel that way because the interface is actually that clunky, or if I’m just inexperienced with Swift scripting. In any case, here’s how it works.
Updated: 18 Mar 2021
Xcode’s UI testing framework has had its ups and downs over the years. Most recently, it has been much more robust and reliable in my experience. However, tests still tend to flake sometimes. Here are some ways that I have been able to reduce flakiness in UI tests.
I have been periodically deleting my tweets for a while now. Yesterday, I finally found a reliable solution for deleting my Twitter “likes” as well and I spent some time deleting all of them. Long ago, I also deleted all of my content on Facebook and Instagram. If you are interested in purging your social media accounts, here are some options.
Oakland has been anything but normal over the past year during the pandemic. But we are starting to see glimpses of normality. Little by little, the whole country is returning to “business as usual”, as they say. And the first real indication that normality is on the horizon for the US was a recent story out of Arkansas.
The Touch Bar on my MacBook started freezing and experiencing UI glitches recently. It was completely unresponsive. At the time, the only way I knew to fix it was to reboot my entire machine, which felt ridiculous. Luckily, there is a better way.
Earlier this year, I decided to re-implement analytics for my site after discovering a viable privacy-aware (and open-source!) alternative to the user-hostile spyware garbage that we call Google Analytics. I have really enjoyed using GoatCounter and I highly recommend it. Now that I have this data, I thought it would be fun to share my top 10 most popular posts in 2020.
Continuing my (still somewhat recent) tradition, here are the books I read in 2020. You can find previous years under the #reading-list tag. I really thought I was going to be able to read a lot more this year, but fuck this pandemic and fuck 2020 all around. There were many weeks where I simply could not focus on much of anything.
Today I cleaned up my various projects and todo’s in OmniFocus. I am always collecting links and resources for potential project ideas, or for general learning. Sometimes, however, it is best to acknowledge that I will likely never have enough free time to even begin some of these endeavors.
This is a first for me. I returned to my MacBook after leaving it for a couple of hours, and it was shutdown even though I left it powered on. The machine was idle. I didn’t have any specific tasks running. I figured it might have been a macOS kernel panic, but upon rebooting I discovered that the crash was caused by bridgeOS.
Updated: 15 Dec 2020
Part of the joy of having a ‘bare bones’ DIY host is that sometimes you have to figure shit out on your own. I am not a great web developer, nor a Ruby expert. But, I learn more each time something breaks — you know, Type II fun. Most recently, I came to understand and fix a new error on my web server:
env: ruby26: No such file or directory.
After reading my recent satire piece, a good friend of mine (and tech worker) asked if I had a list of books or other resources to learn more about labor history and capitalism in the United States, and how the tech industry operates in this broader context. I had been meaning to write about this, and I figured others would likely be interested, too. So, if you are interested in these topics then this is post for you!
Dear COMPANY NAME team:
Hello employees — or should I say independent contractors?! (More on that shortly.) I’m writing to you from my second mansion located in ECONOMICALLY DESTABILIZED COUNTRY IN THE GLOBAL SOUTH EXPLOITED BY UNITED STATES IMPERIALISM! I see the poor children here, and it just reminds me how privileged all of us are to live in a virtuous place like Silicon Valley (at least when I’m there, lol) where we pretend homeless people simply don’t exist. And if they do, it’s because they didn’t try hard enough to do a startup or they didn’t have enough generational wealth to do financial crimes.
I was never a fan of failable initializers in Swift. I do not think this is the correct place to fail and return
nil most of the time. Of course, there are exceptions where a failable initializer is appropriate. But there is another behavior of which to be aware. When constructing a class via a failable initializer,
init?() — or a throwing initializer,
init() throws — the deinitializer,
deinit, is not called if initialization fails or throws, respectively.
You know, the thing that is actually most disheartening, disappointing, frustrating, and plainly sad about Apple’s surprise announcement today is that we will not receive any sort of response to our collective dismay. There will be no public acknowledgment, much less an apology (not that it would help much). Only silence.
I’m currently reading Marquis Bey’s Anarcho-Blackness: Notes Toward a Black Anarchism. These are some reflections on and excerpts from the fourth chapter, titled Unpropertied. This post comes against the backdrop of continued protests and uprisings here in Oakland and the rest of the Bay Area in solidarity with Minneapolis, Kenosha, and the broader fight against police violence.
Updated: 06 Oct 2020
Out of nowhere today, when I tried to run
pod install on my machine, it could not be found. Uh… what?
Updated: 06 Oct 2020
Update: This post was originally written during Xcode 12 beta 3, but has been updated to reflect the final release of Xcode 12.
Xcode 12 was released and it includes a change to how tabs and navigation work. In Xcode 12, the tabs have their own tabs. It makes no sense to me. I know we are supposed to be nice to each other about software, but this new UI/UX is beyond incomprehensible. What made it worse is that this new “tabs within tabs” was the default setting (overriding preferences I had previously set) and I could not figure out how to restore the previous (desired) behavior.
The release notes for Xcode 12 beta state that the release “supports on-device debugging for iOS 9 and later, tvOS 9 and later, and watchOS 2 and later.” I am not sure if that means support for building and deploying for iOS 8 is completely removed, but it sounds like it. Who is still deploying to iOS 8, anyway?
While debugging some code the other day, I wanted to verify the behavior of global variables and static members in Swift. I vaguely remembered from the early days of Swift, that
static let members and global constants were atomic and computed lazily — one of the many improvements over Objective-C.
I like to keep my devices for a long time — as long as possible, actually. I do not need (nor want) a new iPhone and MacBook every year, or even every other year. (Or more!) Putting Apple’s issues aside, the company is quite good at keeping old hardware running the latest software, and generally their hardware is very high quality (except for the utter clusterfuck that was “keyboard gate”). I find it pretty easy to keep devices for 4-6 years, if they are taken care of.
I try to have only one Xcode installed at a time for simplicity and tidiness. But such a setup is rare as we often must manage stable releases and beta versions simultaneously.
I am infuriated. Yesterday morning I woke up to the news that in my hometown of Louisville, KY Breonna Taylor was murdered by the police while she was sleeping. Because she was Black. She was shot 8 times. I do not need to list the names of every innocent and unarmed (or sleeping!) Black human being who has been murdered on the streets or in their own homes by the police in this country. You already know them. This has happened so many times before, from the lynchings in the 1800s to LA in 1992 to Louisville today.
The other day Slack went down and I tweeted to express my dissatisfaction and sarcastically comment that non-native apps are the future. I should have known it would get as much attention as a tweet about Elon Musk. People argued about the merits of native versus non-native app development, which seems like a never-ending a controversy. However, I really do not care which technologies are used to make an app. I only care about the quality of an app and the user experience it provides — which is the problem with Slack.
I removed Google Analytics on this site over two years ago. It was doing more harm than good. I did not want to jeopardize readers’ privacy. I did not want to be part of the bullshit web. I did not want to contribute to Google’s massive data collection and its take over of the open web. I did not want to be Google’s product. (Because fuck Google.)
I rarely even looked at those analytics back then. However, since going independent last year, I have more interest in knowing and understanding the traffic on this site. I found a fantastic solution for analytics that is simple, private, and open source called GoatCounter.
I few months ago I wrote a script to override status bar display settings in the iOS simulator using the new
simctl status_bar feature in Xcode 11. This was great, but it still required that you manually run the script after launching simulators. This was not ideal, as Dave pointed out in iOS Dev Weekly when he challenged me to automate this anytime a simulator launches.
Updated: 14 Apr 2020
When I first upgraded to macOS Catalina, there was a “Relocated Items” folder on the desktop. Well, actually it was an alias to
/Users/Shared/Relocated Items/. This was expected, given the new “security features” in Catalina, which includes a new read-only system volume. What I did not expect was to see this folder reappear with every single update.
I’ve been working on two small libraries for building menu bar Mac apps and now they are both open source with initial 1.0 releases.
For an iOS project that I am currently working on, I am implementing Dark Mode. The codebase is approaching 7 years old, it is mostly Swift with some legacy Objective-C, and it currently supports iOS 11 and above. Aside from the tedium of ensuring the updated colors are being used throughout the codebase, I expected this task to be straight-forward. However, there were some unanticipated issues.
Updated: 23 Mar 2020
JetBrains recently released a new typeface for developers and I wanted to give it a try. I switched to JetBrains Mono in my two primary editors, Xcode and Sublime Text. Much to my surprise, I really enjoyed it. I think it is a great typeface. But I quickly discovered that I hate ligatures.
Last year Xcode 11 was released with integrated support for the Swift Package Manager. For a couple of small projects of mine, I decided to try using it to manage dependencies instead of CocoaPods. Overall, using SwiftPM was a great user experience, but (as expected) it has clear shortcomings due to its lack of maturity.
I recently discovered that unit tests and UI tests for a macOS Xcode project will fail with obscure error messages if the hardened runtime is enabled. It took me awhile to realize what the actual source of the problem was, because the error messages led me in the wrong direction. Hopefully this will save you some time.
Every open-source author, maintainer, and contributor knows the importance of fostering a positive environment for collaboration and providing adequate resources for folks to seek help and contribute in a meaningful way. These resources include providing a Code of Conduct, a Contributing Guide, issue templates, and more. GitHub refers to this collection of documents as community health files, and they have been slowly improving their support for them. I recently spent some time creating defaults for these files, including crafting a completely new Contributing Guide for all of my projects.
Xcode has a great UI for setting and editing breakpoints. I use breakpoints all the time while working and debugging, but I want to share another, unconventional way that I use them.
I love OmniFocus. It is an indispensable app for me and a great Mac app. For managing and organizing to-do lists and personal projects, there is nothing better. Being a great Mac app means adopting behaviors that users expect, conforming to macOS UI/UX paradigms, and for the truly great mac apps it means being scriptable. I want to share two AppleScripts that I wrote for OmniFocus to automate one of my common workflows.
I recently needed to determine when the user has manually switched between dark mode and light mode on macOS. In my menu bar app, Lucifer, the icon reflects the current appearance setting when you change it from the app — an inverted pentagram for dark mode and an upright pentagram for light mode. But there’s a bug. If the user manually changes the appearance setting from System Preferences, or if they are using the new “auto” setting in macOS Catalina, the icon gets stuck in its previous state.
I have started using GitHub Actions for CI on a new project as a replacement for my usual setup on Travis CI. It generally seems to be much faster and more reliable so far. It also has an equivalent feature set, as far as I can tell. But one issue that I have run into is selecting a specific Xcode version, which is a bit cumbersome and not fully documented.
Updated: 30 Sep 2019
The Bay Area Council Economic Institute recently released a report titled Bay Area Homelessness: A Regional View of a Regional Crisis. Unfortunately, I did not have time to read the entire report, but the executive summary contains some interesting bits. If you have time to read at least that, I’d recommend it.
Notes and excerpts from The Fire Next Time by James Baldwin.
Unfortunately, iCloud does not have a good reputation for being reliable, especially during beta releases of iOS and macOS. Yet a lot people still use it, often without any problems. I still use it, despite a few bad experiences in the past, because the best alternatives are questionable for other reasons. I’ve had good luck with iCloud Drive for the past few years, but I am terrified and paranoid of getting caught in the middle of an iCloud clusterfuck, so I backup what I have in iCloud periodically using
Updated: 28 Sep 2019
With version 11 of Xcode, the IDE ships with a new feature in the
simctl tool that can override status bar values for iOS simulators. This allows you to take better screenshots for the App Store without having to worrying about the time, battery level, etc. It is a great improvement, but there are some significant shortcomings. I’ve written a script to fix at least some of those.
As some of you may know, I recently quit my job in San Francisco to pursue personal projects, freedom (sort of) from our collective capitalist nightmare, and self-determination. But I’ll write more on that later. This post is about dealing with health care as an independent software developer in the United States.
I recently released a menu bar Mac app called Red Eye. It’s free and you can download it here. It prevents your Mac from going to sleep. Yes, it is a clone of the beloved Caffeine. And yes, it is the second menu bar app that I’ve made recently. It is notarized by Apple, so you shouldn’t have any problems installing it. I hope you enjoy it!
I’ve been eating vegetarian (and often vegan) for a decade now. I don’t talk about it much. This is a choice I’ve made for myself and my own reasons. What I never imagined happening is the growing popularity and wide availability of vegan/vegetarian food. It is simply remarkable.
This isn’t complicated, but I found it confusing. Perhaps I am spoiled by the more modern APIs in
UIKit. When writing Lucifer, a menu bar app, I wanted to have different actions for left-clicking and right-clicking on the button in the menu bar. To my surprise, this was much more cumbersome than I expected.
I deleted my LinkedIn account, well sort of. I kept my account open, which I will explain below, but I left it mostly empty. You could say I am now officially linked out.
A friend recently sent me The short instructional manifesto for relationship anarchy by Andie Nordgren. It is short and a good primer on relationship anarchy if you are not familiar. Take a look.
I made my first Mac app — Lucifer. It is a menu bar app that allows you toggle Dark Mode on and off in macOS Mojave. To be honest, it feels like a stretch to actually call this a Mac app. It is less than 100 lines of code in a single
AppDelegate.swift file and the meat of the program is an AppleScript that tells System Preferences to enable or disable Dark Mode. As an iOS developer, much of the experience was familiar. The most salient aspect, however, was learning the frustrating and obscure details of app sandboxing, the “hardened runtime”, and app notarization — altogether it was like visiting hell and giving Satan a bubble bath. Appropriate, I suppose.
I intend to start a new series of posts called Reading Notes where I publish notes, excerpts, and thoughts on what I’m currently reading. My goals are to better document my notes and thoughts on what I’m reading for my future self, and give myself a reason to write more blog posts (in general, but also more non-technical ones). I also hope to inspire you, dear reader, to read some of these books and essays.
Here’s the list of the books I read in 2018. There are 36 in total. At first it seemed like a small number to me. However, that averages to three books per month, which actually feels like a lot. In fact, I’m not sure I could read more than three books each month. There was never a time last year when I wasn’t reading something, and I often read multiple books at once.
The other day I was debugging a crash in a UI test for an open pull request at work. The bug turned out to be extremely subtle and difficult to notice. I spent way too much time staring at the changes, trying to understand what was wrong. Let’s see if you can spot the error.
There’s a place called North Berkeley Frame in downtown Berkeley on Shattuck. It’s a framing shop and gallery (sort of) run by this guy named Lars. He’s older, probably mid-fifties or early sixties. He has gray hair, a gray beard, and a gentle face. I’ve had him frame some prints and other artwork for me. He’s always helpful in choosing the right frame, and his work is excellent. Like many older folks I know, he loves to talk.
Fifteen years ago today my sister died. Most people don’t know about her — Amy. I don’t talk about her much, because talking about death makes people uncomfortable, especially when the loss was so traumatic for those left behind. I was 14, she was 16. It feels like it happened a lifetime ago and that it just happened yesterday, all at once.
I haven’t read the book, The Four Agreements, but I will eventually. However, simply knowing what the Four Agreements are has been tremendously helpful for me. They may help you, too. I want to write them down to share, but also to remember them better and have a reference to revisit in the future.
A common scenario in app development is to build up a list of objects, perhaps to display to the user or for another purpose. Maybe you’re fetching data from a database to display, or constructing fields to display for an interface. Consider the iOS Calendar app, for example. When you add a new calendar event, the form displays all the fields you can fill-in — title, location, date and time, notes, etc. However, when viewing an existing event all you see are the completed fields while the uncompleted fields are hidden.
The mayor of San Francisco called out feces on the sidewalks as a core problem to address in the city and wants homeless folks to “at least have respect” and “clean up after themselves”. It’s an unfortunate response, but I’m sure a lot of folks agree with the sentiment. No one relishes walking through the dirty streets in this city and it certainly is a concern, but this kind of rhetoric is actively harmful. It deliberately shifts responsibility for the problem onto the victims and away from the system that produced it. Homeless folks are among the most vulnerable in our society. In addition to their lack of housing, persistent precarity, mental health issues, and emotional struggles, the city is now going to ask them for respect and cleanliness?
One of the major changes in Swift 4.2 is a change to the calling convention. But what exactly does that mean? Why is it important and why would you want to change it?
Net Neutrality is officially over in the US. As the EFF notes, it will likely manifest as a slow, painful decline of the Internet. We can call congress to demand that they reverse the decision and act in the interests of the people. But whether or not that succeeds, everyone should be using a VPN regularly now to fight against the growing threats of Internet surveillance and censorship. We know better than to trust corporations and governments.
I finished reading Chimamanda Ngozi Adichie’s new book, Dear Ijeawele, or a Feminist Manifesto in Fifteen Suggestions. You should read it. As well as We Should All Be Feminists while you’re at it.
I recently discovered a preference in Xcode’s Navigation settings that makes the ‘Assistant Editor’ much more useful, especially when writing Swift.
I had a great time at WWDC this year, meeting new friends and catching up with old ones. Those experiences are the ones that matter the most to me. The newly announced tech is interesting and fun, but ultimately fleeting and ephemeral.
In a recent episode of the podcast, JP and I discussed the implicit escaping of closures in Swift. As Swift has matured and evolved, the default behavior of closure parameters in functions has changed. Prior to Swift 3, closures parameters were escaping by default. After SE-103, the default was changed to non-escaping.
Updated: 17 Mar 2021
I’m not interested in being an advertising product for Google to exploit. I’m also not interested in the company’s unsavory practices, in general. I’ve been using DuckDuckGo for over a year now, and I’m incredibly happy with it as a replacement for Google Search — not only for personal usage, but also for implementing a custom search component for this site.
Updated: 05 Jan 2019
When you file a radar for a bug on one of Apple’s platforms, you should (usually) always attach a sysdiagnose. A sysdiagnose provides a lot of helpful information for the person who is trying to understand how the bug happened. Amongst other things, it contains logs from various parts of the OS, and all recent crash logs. Without it, the person on the other end of your report inside Apple may not be of much help. On macOS running sysdiagnose is somewhat common, but what about iOS?
Updated: 08 Feb 2018
Next week’s issue of Swift Weekly Brief will be its 100th and final issue. I started this newsletter a little over two years ago, covering the initial open sourcing of Swift, the 3.0 release, the 4.0 release, and many significant milestones in-between for the language and the community. With few exceptions, there was a new issue every week thanks to the other amazing writers and contributors. The newsletter quickly became an important resource for the Swift community. Because of this, I’m sure many of you will be saddened to hear that the 100th issue will be the last. At least, Issue #100 will be the last issue for me, for now — but if someone from the community is willing to take over this project, it can continue.
Updated: 18 Apr 2018
ε. The fifth letter of the Greek alphabet. In calculus, an arbitrarily small positive quantity. In formal language theory, the empty string. In the theory of computation, the empty transition of an automaton. In the ISO C Standard,
1.19e-07 for single precision and
2.22e-16 for double precision.
The other day I was attempting to use
FLT_EPSILON (which I later learned was laughably incorrect) when the Swift 4 compiler emitted a warning saying that
FLT_EPSILON is deprecated and to use
.ulpOfOne instead. What the hell is
ulpOfOne? I read the documentation and then everything made sense — ha, just kidding. The
FloatingPoint.ulpOfOne docs generously describe the static variable as the unit in the last place of 1.0 — whatever that means. Let’s find out.
PlanGrid is a productivity app for construction fieldworkers. The easiest way to explain it to software developers is that it’s like an IDE, Git, and GitHub or JIRA — but for construction. Think of all the amazing software tools we have to do our jobs as programmers. The equivalent tools for construction simply did not exist before PlanGrid, and they still have a lot of room to grow.
As software developers, we build software for specific purposes. We anticipate that people will use an app in certain ways. Yet, we often discover that users are behaving differently than we expected. They hack a custom, “unsupported” workflow to workaround an app’s unintended limitations. Once we realize this, we have the power to turn these user workarounds into first-class features. However, sometimes we find that our apps are being used in totally different, unimaginable ways.
At PlanGrid, we recently discovered that the app was being used as a digital archaeological tool.
The Swift type-checker remains a performance bottleneck for compile times, though it has improved tremendously over the past two years. You could even say the type-checker has gone from being drunk to sober. To help users debug these issues, awhile back Jordan Rose added a frontend Swift compiler flag that would emit warnings in Xcode for functions that took too long to compile, or rather took too long to type-check. In Xcode 9, there’s a new, similar flag for checking expressions.
Updated: 07 Oct 2020
This site used to be hosted via GitHub Pages, but I decided to move to a dedicated host to have more control over how I develop and deploy the site, and how it’s configured. A number of limitations and quirks eventually drove me to migrate away from GitHub pages to my excellent and inexpensive bare-bones host, NearlyFreeSpeech.net. I was also interested in learning to do all of this on my own, rather than relying on GitHub Pages “magic”. If you’re looking to setup your own Jekyll-powered site, or if you’re looking to migrate off of GitHub Pages, hopefully this is helpful.
Data & Society recently released a stunning report, Media Manipulation and Disinformation Online. I highly suggest you read it if you care about understanding the rise of neo-fascism, the ‘fake news’ phenomenon, and manipulation of the media that plagued the 2016 US Presidential Election — and how Silicon Valley, particularly social media platforms, facilitated the rise of the alt-right movement and the spread of fascist propaganda. Don’t let the more than 100 pages deter you. The core report is only 50 pages, followed by a few pages of case studies, and finally a whopping 45 pages of citations and bibliography. (Direct download)
The Swift community has been through some rough migrations. It is frustrating when your project no longer compiles because of API and syntax changes, but it is an entirely different story when your project seg faults the compiler. When that happens, you cannot simply run a migration tool or apply fix-its — your project is broken and there’s little you can do until a fix is released. This is why the swift-source-compat-suite project was created.
Updated: 18 Jul 2017
Beginning immediately, JSQMessagesViewController is no longer officially supported or maintained. In fact, you may have noticed that it has been neglected for the past year. The most recent release was published almost exactly one year ago today. This is an incredibly difficult post for me to write and I have not made this decision carelessly. This open source project had a great run. There was (and still is) a great community around it, and I’m sorry for bringing this to an end.
Protocols in Swift and Objective-C are a powerful tool to decouple your code. They allow you to specify a contract between classes that consume them, but defer a concrete implementation to conformers. They allow you to segregate interfaces and invert control. One interesting aspect of protocols in Swift and Objective-C is that protocol members can be optional (
optional in Swift or
@optional in Objective-C). Unfortunately, this comes with a number of disadvantages and diminishes the robustness of your code, so it is often avoided. However, having optional members is sometimes the right conceptual model for your design. How can you design your protocols to provide optional semantics without specifying them as
In a previous post I discussed strategies for using singletons in a cleaner, more modular way. Singletons are a fact of software development, especially in iOS. Sometimes the design pattern actually is the right tool for the job. In those situations, how we can improve the way we write our own singleton classes?
Earlier this week, the Tech Workers Coalition and UNITE HERE! in San Francisco hosted a panel discussion on how we can use our power as consumers to support hotel workers in the Bay Area and across the United States. The tech industry is full of remote workers, as well as conference organizers that host thousands of conferences each year — meaning thousands of programmers, designers, product managers, and others travel all the time to attend these conferences or attend their own company’s events. By choosing to stay at a fair hotel, you can make a significant impact on an industry where workers are struggling to negotiate fair wages and benefits.
There has been a ton of debate on the swift-evolution mailing lists about access control in Swift. A couple of days ago, the proposal SE-0159: Fix Private Access Levels was rejected. I want to share my thoughts on this, as well as thoughts on the larger story for access control in general. But first, let’s begin with a brief history of access control in Swift.
A few months back, JP Simard and I decided to start a podcast about Swift — the language itself, its evolution and development, the Swift.org open source projects, and general Swifty news. There are a ton of great podcasts out there about developing for Apple platforms and Apple news, but there’s nothing exclusively about Swift the language. In many ways, this podcast is an extension of and commentary on the Swift Weekly Brief newsletter. However, we’ll be doing deep dives on various topics and elaborating on concepts in greater detail. I’m excited to share that we launched Swift Unwrapped yesterday with Spec.fm!
In software development, singletons are widely discouraged and frowned upon — but with good reason. They are difficult or impossible to test, and they entangle your codebase when used implicitly in other classes, making code reuse difficult. Most of the time, a singleton amounts to nothing more than a disguise for global, mutable state. Everyone knows at least knows that is a terrible idea. However, singletons are occasionally an unavoidable and necessary evil. How can we incorporate them into our code in a clean, modular, and testable way?
A few months ago, I spoke at Swift Summit in San Francisco. The conference has a reputation for providing high-quality talks, and this year was no different. Fortunately, I was able to see nearly all of the talks and not a single one disappointed me. It was such a great conference. The video and full transcript of my talk are now available. The videos of the other talks will be coming online over the next few weeks. I would recommend watching all of them!
OCMock is a powerful mock object unit testing library for Objective-C. Even if you are using Swift, as long as your classes inherit from
NSObject, you can use some of its features. But what if you are writing pure Swift code which does not have access to the dynamic Objective-C runtime? Or, what if you don’t want your Swift code to be hampered by
NSObject subclasses and
@objc annotations? Perhaps, you merely want to avoid dependencies and use ‘plain old’
XCTest with Objective-C. It’s relatively easy and lightweight to achieve the same effect in some testing scenarios without using
You may have noticed that I did not write the last few issues of the Swift Weekly Brief. I took some much needed time off, and I was able to unplug and relax thanks to the wonderful JP Simard and Brian Gesiak. They took over for those weeks and I can’t thank them enough! Bas Broek also made regular contributions, which was super helpful.
I recently spoke at the FrenchKit conference about Swift Evolution. The talk, 140 proposals in 30 minutes, was originally intended to be an overview of the process and each of the proposals. However, as I was writing the talk, it evolved into something much more interesting. I ended up writing some code to analyze the proposals instead.
I’m happy to share that all of my open source Swift libraries have (finally) been updated for Swift 3. If you’ve been waiting for any of these final releases, you can now run
pod update or
carthage update and relax — sorry it took so long! I wrote about migrating to Swift 3 a few months ago and this post shares the final results of the process that I outlined in there.
Last week I attended and gave a talk at FrenchKit in Paris, France. As expected, it was an amazing conference — especially considering it was the first FrenchKit ever. I think the organizers are already thinking about FrenchKit 2017, so keep an eye out and definitely go if you can. I know I will.
One of the most common patterns I see in software design with Objective-C (and sometimes Swift), is the use of enumeration types (
enum) as configurations for a class. For example, passing an
enum to a
UIView to style it in a certain way. In this article, I explain why I think this is an anti-pattern and provide a more robust, modular, and extensible approach to solving this problem.
I spent most of my free time last weekend and a few days of last week on migrating my Swift code to Swift 3.0 — I migrated my open source projects as well as my private side projects. Overall, I would say my experience was “OK”. It definitely could have been better, but I think the largest problem was overcoming the cognitive hurdle of seeing all the changes and errors from Xcode’s migration tool at once. The best thing to do is wipe away the tears, put your headphones on, and start hacking. 🤓
As developers, we’ve been lamenting the continued existence of the inferior A5 system-on-a-chip for the past couple of years. Both iOS 8 and iOS 9 continued to support iPhone 4S, iPad 2, and iPad Mini 1 — devices that struggled to run the OS itself. I had hoped that iOS 9 would finally drop support for these less powerful devices, but it didn’t. Today, we can finally say goodbye to the A5. Well, almost.
A few days ago I was (finally!) updating a project to use Swift 2.2 and I ran into a few issues when converting to use the new
#selector syntax introduced by proposal SE-0022. If using
#selector from within a protocol extension, that protocol must be declared as
@objc. The former
Selector("method:") syntax did not have this requirement.
I recently had an incredible experience with one of my open source projects that I’d like to share. It’s a story of openness and collaboration that I hope other open source project maintainers will find valuable. This post continues the theme of “building successful open source projects” from my previous article on documentation.
Updated: 18 Apr 2018
Earlier this month I had the incredible opportunity to speak at the try! Swift conference in Tokyo, Japan. 🇯🇵 It was such a fun and rewarding experience. A video of the talk is now online over at Realm’s blog, where it is synced with my slides. If you have not already seen it, go check it out!
Do you love writing code? Are you passionate about open source? Do you want to get more involved, but have yet to find a project to which you want contribute? Are you interested in contributing to a widely used, impactful project? Then I have a proposition for you! I am looking for dedicated core contributors to help maintain JSQMessagesViewController!
In case you are late to the party, I finally found some time to give the Swift Weekly Brief a proper home. Starting this newsletter kind of happened by accident when I first wrote about the Swift open source announcement. Since then, it was kind of bootstrapped here on my personal blog and started to feel awkward. I hacked together the new site in a couple of nights and moved all the previous posts over. Today’s issue #5 is the first one to be originally published at swiftweekly.github.io. However, there is more here than just organization and a nice separation of concerns.
Now that the holidays are over, things have started to pick up again on Swift.org. If you are following any of the repos on GitHub, you have probably noticed. I’m not sure how I missed this before, but this week I just discovered SwiftExperimental.swift. For now, it defines a bunch of custom unicode operators for
Set. It’s really cool. I would love to see more APIs like this in the standard library. Anyway, here’s the weekly brief!
As expected with the holiday season, things are slowing down for a bit on Swift.org. I have been traveling for the holidays as well, so this issue will be shorter than usual. If you haven’t already, be sure you take some time away from coding to enjoy the holidays and avoid burnout. Now, the weekly brief!
The Swift.org community is finishing up its second full week of open source development. If you were hoping for a quiet week, you will definitely be disappointed. There is still a ton of activity with no signs of slowing down. The Swift team continues to work openly and to be encouraging to contributors. This week brought more crash fixes and more Swift Evolution proposals. Let’s get to it — the weekly brief!
It looks many developers in the community enjoyed my previous post detailing my thoughts and observations on the activity around the Swift open source project. So, I’m going to try to do this weekly — every Thursday, since the open source announcement was on a Thursday. Each week I’ll provide a high-level summary of what’s been happening, updates on interesting statistics, and links to interesting content. If you have any suggestions, please let me know! And now, the weekly brief!
In iOS development, the core of nearly every app rests on the foundations provided by
UITableView. These APIs make it simple to build interfaces that display the data in our app, and allow us to easily interact with those data. Because they are so frequently used, it makes sense to optimize and refine how we use them — to reduce the boilerplate involved in setting them up, to make them testable, and more. With Swift, we have new ways with which we can approach these APIs and reimagine how we use them to build apps.
Updated: 03 Jan 2021
Updated: 23 Jul 2015
Mike Ash has a great Friday Q&A on namespaced constants and functions in C. It is a powerful and elegant technique to avoid using
#define and verbose Objective-C prefixes. Although Swift types are namespaced by their module, we can still benefit from implementing this pattern with
enum types. I’ve been experimenting with this approach for constants in Swift and it has been incredibly useful.
I recently gave a talk at the Swift Language User Group (#SLUG) meetup at Realm in San Francisco. A video of the talk is now online over at Realm’s blog, where it is synced up with my slides. If you haven’t already seen it, go check it out! Realm does an absolutely amazing job with posting these meetup talks — in addition to the video and slides, there’s a full transcript and subtitles.
In a previous post, I discussed how Swift’s failable initializers could be problematic. Specifically, I argued that their ease of use could persuade or encourage us to revert to old (bad) Objective-C habits of returning
init. Initialization is usually not the right place to fail. We should aim to avoid optionals as much as possible to reduce having to handle this absence of values. Recently, @danielgomezrico asked a great question about a possible use case for a failable initializer — parsing JSON. Given this problem’s popularity in the Swift community, I thought sharing my response here would be helpful.
The observer pattern is a powerful way to decouple the sending and handling of events between objects in a system. On iOS, one implementation of this pattern is via NSNotificationCenter. However, the
NSNotificationCenter APIs are kind of cumbersome to use and require some boilerplate code. Luckily, Swift gives us the tools to improve
NSNotificationCenter with very little code.
As I continue my work with Core Data and Swift, I have been trying to find ways to make Core Data better. Among my goals are clarity and safety, specifically regarding types. Luckily, we can harness Swift’s optionals, enums, and other features to make managed objects more robust and more clear. But even with the improvements that Swift brings, there are still some drawbacks and limitations with Xcode’s current toolset.
Core Data is probably loved as much as it is shunned by iOS developers. It is a framework of great power that often comes with great frustration. But it remains a popular tool among developers despite its pitfalls — likely because Apple continues to invest in it and encourages its adoption, as well as the availability of the many open-source libraries that make Core Data easier to use. Consider unit testing, and Core Data gets a bit more cumbersome. Luckily, there are established techniques to facilitate testing your models. Add Swift to this equation, and the learning curve gets slightly steeper.
A few weeks ago I published the sixth major release of
my our messages UI library for iOS. This release closes the door on a major milestone for this project, so I wanted to take the time to highlight its significance, discuss its new features, and examine its design. Of course, this would not have been possible without our amazing open-source community and the contributors to this project.
I’m incredibly happy and incredibly proud to share that Rosetta Stone is an open-source software contributor. Since I started working at Rosetta Stone a little more than a year ago, I’ve been encouraging and advocating for the company to get involved in open-source. Today, we did just that. Today is a big day for Rosetta Stone.
Swift is still young and ever-changing. With each release, we have seen dozens of tweaks, additions, and deletions. And there is no reason for us to think that this rapid evolution will decline anytime soon. To remind us of exactly that, the latest post on Apple’s Swift Developer Blog introduces a new feature in Swift 1.1 in Xcode 6.1 — failable initializers.
When the App Store launched, there was one iPhone with one screen size and one pixel density. Designing your user interfaces was relatively simple and the technical debt of hard-coding them was cheap. Today, developers and designers face many challenges in creating apps that must work on dozens of different devices. Long gone are the days of 480x320. We can no longer depend on physical screen sizes and must always be prepared for the next generation of devices.
When I find my code is slow or troubled, friends and colleagues comfort me. Speaking words of wisdom, write in C. It is understood that foregoing the features and abstractions of high-level programming languages in favor of their low-level counterparts can yield faster, more efficient code. If you abandon your favorite runtime, forget about garbage collection, eschew dynamic typing, and leave message passing behind; then you will be left with scalar operations, manual memory management, and raw pointers. However, the closer we get to the hardware, the further we get from readability, safety, and maintainability.
As Apples to apples, Part II made its way around the web, it was praised as well as critiqued. The latter largely consisted of questions regarding the real-world applications of these benchmarks. In general, benchmarks should be taken with a grain of salt. I want to take a minute to clarify my thoughts on benchmarks and how I think they can be valuable.
If at first you don’t succeed, try, try again. Practice makes perfect. These proverbs have encouraged us all in many different contexts. But in software development, they tug at our heartstrings uniquely. Programmers persevere through countless nights of fixing bugs. Companies march vigilantly toward an MVP. But after 1.0 there is no finish line, there is no bottom of the 9th inning. There are more bugs to be fixed. There are new releases ahead. The march continues, because software is not a product, it is a process.
Updated: 13 Oct 2014
You have spent countless hours, days, months, or maybe even years perfecting your app. There has been plenty of blood, sweat, and tears. Your relationships and your health have suffered through the development process. You are ready for 1.0 and the time has arrived to prepare all of your content for the App Store — app icon, keywords, description, localizations, and screenshots (and soon app previews).
Updated: 01 Aug 2014
When Craig Federighi arrived at his presentation slide about Objective-C during this year’s WWDC keynote everyone in the room seemed puzzled, curious, and maybe even a bit uneasy. What was happening? As he continued, he considered what Objective-C would be like without the C, and the room abruptly filled with rumblings and whispers  as developers in the audience confided in those around them. If you had been following the discussions in our community about the state of Objective-C (and why we need to replace it) during the previous months, you could only have imagined one thing: Objective-C was no more — at least not as we knew it.
XKCD’s posts on saving time and automation are precisely how this blog came to be. Until now, I never had the time or motivation to write on a regular basis, though I considered it often. I’ve been developing for iOS for a few years now and I’ve become increasingly involved in the Objective-C open-source community via GitHub and CocoaPods, and was lucky enough to attend (my first!) WWDC this year on its 25th anniversary. It was an awesome experience. With that said, I can’t think of a better time or better reason to begin writing about my experiences with iOS and Objective-C (and now Swift), as well as my involvement in open-source. I hope to share worthwhile and interesting things here.