All about xcframeworks

May 19, 2023

You may have heard about xcframeworks and how they are a way to distribute libraries on Apple platforms. But documentation on the format is hard to come by. With this blog post I hope to summarize everything you need to know about xcframeworks and put it all in one place for your reference.

This section provides a rationale for the existence of xcframeworks. Feel free to skip it if you’re not interested.

Before xcframeworks were defined, there was no Apple-supported way to distribute libraries for more than one platform at a time. This wasn’t really a problem for a while, since the only Apple platform a developer could build a framework for was OS X. Even when the Mac switched from PowerPC to Intel, the single-framework model survived because it was possible to create Universal “fat” binaries that contained more than one architecture slice. Since a framework would still target a single platform, including a Universal binary worked quite well.

When Xcode began supporting frameworks for the iPhone SDK, the picture became more complicated, since developers had to deal with two new platforms: iPhoneOS and iPhone Simulator. Developers could ship two frameworks—one for each platform—but it was not easy to consume two distinct frameworks in a project that should be easily built for both iPhone hardware and the simulator. While build-settings tricks could be employed to switch FRAMEWORK_SEARCH_PATHS depending on the build platform, the lack of automatic support in Xcode for doing so made it a difficult chore.

One workaround that some developers adopted was to use the lipo tool to splice an arm64 slice from the iOS build of the framework, together with an x86_64 slice from the Simulator build, and distribute a single “Frankenframework” that could be used to build both a device binary and a Simulator binary, without build-settings shenanigans. This hack conflates architecture with platform but it worked…

…until the M1 Mac came along. Since the M1 Mac natively used the arm64 architecture, both iPhone hardware and Simulator builds consumed the arm64 architecture; developers could no longer use architecture as a proxy for platform. Add to that the proliferation of platforms—tvOS and watchOS and their simulators—and it was clear that a better solution was needed.

Apple defined the xcframework format as a way to cut through this chaos. This officially-supported specification allowed developers to distribute the same library built for a variety of platforms and architectures in a single package. Projects that consumed an xcframework needed only specify a single link dependency, and Xcode would switch between platforms and architectures automatically. The xcframework specification is future-proofed enough to accommodate new platforms or architectures Apple might support in the future.

An xcframework is a library distribution bundle

To be precise, an xcframework is a universal, binary, library distribution format. Let’s break that description down in reverse order.

An xcframework is a library distribution format. Each xcframework holds exactly one library. A library is a precompiled collection of code that can be consumed by another project to create an executable (or app).

An xcframework is a binary distribution format. That means it does not include source code in its distribution. Only built binaries and interface specifications (headers and/or Swift interface files) are included.

An xcframework is a universal distribution format. That means it holds libraries and interfaces for different platforms as well as processor architectures in the same structure. A single xcframework can, for example, offer the same library for consumption for iOS, watchOS, and Mac projects using either Intel or ARM architectures.

Finally, an xcframework is a bundle because it’s a directory with a well-defined content structure and file extension, and has an Info.plist file in its root. Examining its Info.plist file shows that it has a CFBundlePackageType of XFWK.

Read more…

Phase-detection autofocus is a bit sloppy

May 13, 2023

Today I learned that phase-detection autofocus is fast and accurate, but not precise—the resulting focus when you hit that AF button is a tiny bit sloppy. When that AF beep is heard, your focus will be ever so slightly front or back of the actual focus point. I’ve even seen evidence on my lenses that that where you left your focusing ring the last time affects whether the next autofocus is front- or back-focused.

This means that you should never simply take the first number that Automatic AF Fine Tune gives you. Instead, take a dozen or more readings and average them out to get a feel for your lens’s focus bias, then manually adjust the fine-tune setting. Take a few photos of a sharp, stationary target, and pixel-peep until you get the setting about right. If you’re like me, you’ll get three super sharp shots out of four, with the last one just a bit soft. Here are my takeaways when using phase-detect autofocus:

  1. When shooting with wide aperture, take a bunch of shots, and hit that AF button each time. Remember, phase-detect AF is probabilistic in nature.

  2. DoF is your friend. Stop down that aperture a bit more to give yourself the best chance of getting your subject in sharp focus.

  3. Don’t bother with AF Fine Tune unless you notice that your shots are consistently back- or front-focused. Most lenses hover around 0 bias out the door unless they’ve been abused.

  4. When shooting a still subject with a tripod, use Live View to focus using contrast-detection. It’s much slower, but it will never misfocus. Alternatively, use manual focus and Focus Peaking.

  5. Don’t pixel-peep too much. As long as your photo looks pretty good on a 2 MP screen, it’s probably good enough. With cameras pushing 48 MP+, even the most insignificant misfocus will look awful at 100% magnification.

On Conservatism and the Persecuted Class

April 15, 2023

Have you ever wondered why American conservatives always seem eager to make life hell for one group or another? Why are they so obsessed with persecuting trans folk today, who make up a tiny minority of the population and cause basically none of society’s problems? I offer a simple hypothesis: American conservatism requires some persecuted class to be defined to justify the ideology’s existence. Without someone to step on, conservatism simply ceases to be. Without something to expunge, there is, by definition, nothing to conserve.

American conservatism is strongly correlated with a hierarchical view of the world. A good way to feed a conservative’s need to feel like they’re on top, then, is to classify someone else as an inferior. A persecuted out-group can be agreed upon to take the blame for society’s ills, so that the in-group can declare themselves blameless. And because the very notion of a blameless class of superiors is ridiculous on its face, a new class of persecuted people must be found whenever a previous group is used up, lest the superior class is left with only themselves to blame.

Read more…

Streaks are bad for you

April 13, 2023

I’m convinced that streaks is an antipattern for healthy habits, and it is actually quite bad for you.

Streaks encourages perfectionism, and undervalues the progressive nature of growth. The goal of any good habit is not to do it every single day, but to do more of it over time.

Streaks punishes you for missing a day by throwing out all your accumulated progress so far—back to zero you go!—even when you have a perfectly wise reason to miss a day’s session. The loss of all your “progress” can be devastating, and people may do damage to themselves solely to keep a streak going.

Stop using streaks in your apps. Use a different metric that encourages growth, not perfection. Try a trailing tally with a target band instead (you did the activity 25 days out of the past 30! Good job!), or let your users view their progress on a calendar without any metric at all, and let them judge for themselves how well they did.

Dealing with Bad News

March 29, 2023

AI-generated image of smashed glass

DiffusionBee-generated image

I had to deal with some potentially awful news a couple of days ago, and I’d like to share with you how I deal with events that knock me off balance. Maybe it’ll help you too.

Read more…