Explainer Technical

Why Swift (isn’t) being undermined of its potential

I saw a question posted to /r/Swift:

Why is Swift being undermined of its potential?

The question was lengthy, but boiled down to “Why isn’t Apple donating resources to turn Swift into a dominant language that does everything?” Well, I’ll tell you.

Apple has one purpose in the world:

  • It buys raw commodities
  • It passes them through manufacturing processes that are cost prohibitive to duplicate
  • It turns the result into a sale at many multiples the cost of the inputs

What is Swift’s potential? To help them generate billions of dollars in margins on great big industrial quantities of silica, aluminum and precious metals through value-add intellectual property. Is it meeting that potential?

Swift didn’t exist when I started making iOS apps. Today, it’s a ubiquitous, eagerly adopted component of the developer experience with a thriving ecosystem of OSS projects, community discussion, and third party documentation. It is laying the groundwork for a unified user interface API that works across all of Apple’s platforms. That’s essential, because platform differentiation requires apps. Without the coolest, most interesting, most beautiful, most socially transformational apps being built for their hardware, Apple doesn’t have a future. Without ongoing growth in hardware margins, Apple doesn’t have a future.

Apple needs to build more hardware platforms, and for those platforms to succeed in the market, they have to have good software ready to roll. Finding strategies to lower the cost of maintaining apps within their ecosystem and across device classes is crucial to the success of that project. The AppKit/UIKit schism was a historical necessity, but an entirely unsustainable long term strategy.

Swift exists to make the process of building those apps more accessible, more reliable, more intuitive, more cross-device scalable for teams of all sizes. Building an entire language, libraries and ecosystem is wildly expensive. Apple does it for strategic benefit, not as a hobby. Within those strategic goals, Swift has been successful at meeting its immediate potential, and as an early adopter of SwiftUI, I think we’ve only seen the beginning of how Swift is a foundation for their long term goals.

If you’re wondering why a strategic asset works the way it does, you just go back to the strategy of its sponsors. No, Swift’s goals and governance don’t work like Go, or like Rust. Its evolution is guided by the priorities Apple has of making magic happen on its own platforms. Anything else that happens is a lower priority, or a second order effect of Apple’s primary strategy.

Explainer Technical

Advice for new iOS developers

Adapted from a reply to a reddit post from a student considering a career in iOS:

If you really want to make iOS your career, the path isn’t as simple as endless articles and tutorials, nor is it cargo culting the “clean coding” practices used to sell books and conference talks. Though sharpening your saw has a lot of value, if you don’t learn what to build with that saw, you’ll never escape the pile of hobbyists.

Once you have enough of the basics understood, you’ll hit diminishing returns if you don’t turn your attention to the real work.

If you want a career in iOS, you must learn to ship. Learn how to take an idea and make the trade offs, compromises and refinements necessary to realize it as a finished product in the hands of real users. There’s endless prattling on design patterns and code style and everything else, but less written on how to actually get a project out the door, since writing nice code in the abstract is easy compared to shipping. But it doesn’t matter because the only real way to learn it is by doing it.

True story: I was once called in to rescue a project for a multinational corporation everyone you know has heard of. It wasn’t anything important or even customer facing, just a test of a new technology for internal, employee use. The guy they’d hired, with experience working at other big companies, couldn’t ship this (simple!) feature to save his life. It was buggy and sloppy and not making any progress despite two months of work. I came in, assessed the path between brokenness and something workable, and we had the project back on track inside of a week. But the guy had a meltdown and, uh, fired himself, because the pressure of shipping this one little thing got to him.

If you don’t learn to ship, you’ll eventually find yourself at a disadvantage at work, since the point of software is to get used by customers.

iOS has perhaps the lowest tolerances for user-facing sloppiness of anything you can get paid to code. An essential meta skill here is learning how to make a reliable, refined experience within the confines of Apple’s App Review process and other rules. But it’s not just the bureaucracy of Apple. It’s the high expectations of iOS users, who expect a reliable, intuitive experience that, by the way, maintains 60 FPS of screen drawing performance.

So you need to learn skills like how to debug weird crashes, and how to interpret user feedback to find bugs. How to profile your code to find performance bottlenecks and resolve them. How to build UI components in a way that they’re easy to iterate on based on the confusion your users are having. This is the valuable experience that helps you sift through the dogma provided in books on how to code right and actually choose practices that serve your project.

This is a lot to juggle, but when you get it right, it’s sublime. The experience of building satisfying stuff on this platform never gets old.

Some important and counterintuitive advice: write shitty code. Don’t be so paralyzed about writing something “the right way” that you don’t make progress at all. Write shitty code, then rewrite it again once you have a bigger picture of the project. Premature fancy architecture can kill you, as you write elegant solutions to problems you don’t actually have, only to rip it down two months later because it didn’t address an edge case that wasn’t visible to you at the time. Write shitty code, and then use the lessons you’re picking up to refine it once you understand the larger system better.

Remember Gall’s Law:

A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.

Shitty code is often a great start for building a simple system you can evolve later. In professional parlance, this need for evolution is called “technical debt,” and learning how and when to remediate it is yet another essential professional skill. The best part is, sometimes you get to throw away shitty code altogether, if the feature it was serving is canceled or de-prioritized, so building it the “right way” will have been wasted effort. The tension between code that’s good enough for right now, versus investments in code that make the project easy to enhance later on, will be present throughout your career.

If you’re going to ship things, you’re going to need to worry about design. Maybe this makes you uneasy: many people who enjoy code don’t have the same confidence with the visual arts. What you must understand is that the most important part of design is how your product works. A minimal visual design that makes it easy for your users to accomplish their tasks is much more valuable than a beautiful design that introduces friction. How it looks does matter: people don’t take ugly software as seriously. But you can get far using the basic system elements tastefully, while observing people actually using your project and improving on the steps they take to meet their goals. Confusing button? Give it a better label. Too many steps to accomplish a common task? Change your navigation around. You can get far by making things work well, even if your ambitions don’t include visual design.

So if you’re asking me, I say that once you’re confident enough from your studies to write workable code, it’s time to pick a project you want to build that solves a real problem, test it with real users, integrate their feedback, and get the code approved in the App Store. Go do that a few times and I suspect your options will be wide open. Best of all, that skillset will serve you no matter the stack or platform you’re using to build user-facing software.

Because maybe the most important advice I can offer is this: platforms come and go. Once upon a time, iOS appeared out of nowhere and changed the face of computing.

Someday, it’ll happen again. Maybe your existing language and API experience will be immediately transferrable—Apple does like to cannibalize its own products to stay on the cutting edge. But maybe it won’t be: surprises are always possible.

Either way, you’ll have to adapt.

Good luck.

Explainer Technical

Communicating state changes between UIKit and SwiftUI

It’s possible, and often necessary, to combine Apple’s legacy UI frameworks with their hottest new technology, SwiftUI. SwiftUI solves some of the most common problems Apple platform developers encounter, but it’s still a 1.0 technology. In the cases where does SwiftUI offer analogous components to UIKit or AppKit, it doesn’t always provide identical configuration options. Moreover, not all existing components have SwiftUI representations.

While the techniques for embedding SwiftUI and legacy view frameworks in one another are straightforward, one head-scratcher for new SwiftUI developers is how to make these views communicate. The old UI paradigm made every single view element its own object. To communicate between objects, you called the method you wanted and that was that.

SwiftUI, on the other hand, computes a view based on state data. Each view is a struct that describes things to be drawn on the screen, rather than an instance of an object. There’s nothing to call methods on.

Nonetheless, it’s possible to bring harmony to these two approaches in a way that is seamless to the end user, and straightforward enough to maintain for your team.