Nov 09, 2020

Getting Into iOS Development with SwiftUI

The process of breaking into a new field is always challenging. I've often felt as if I were being held back by an entry barrier that prevents me from progressing, like a lower boundary. Being persistent, repeating, and learning are the only way to break through this barrier. Sometimes it takes multiple attempts to get started.

Why am I writing about entry barriers, though? After having focused primarily on the web and backend systems up until now, I've been trying to get into application development around iOS and macOS on multiple occasions, most notably a couple of months ago when I tried to build macOS menu bar applications, only to get held back by the depths of native code and platform-specific requirements.

A couple of days I gave it another shot, and I think it clicked. I'm not sure whether it was the additional experience I gained over the last months, or Meng To's amazing course, which I followed for a bit, but I've been able to get up to speed with SwiftUI, building views, basic routing logic, and offline data storage with Core Data, all in a weekend, with little prior knowledge.

While there's still so much to learn, I believe I've finally reached the point where I can improve on my own, which is an exciting feeling.

I quickly noticed a couple of similarities to designing large React applications with complex state management, some of which I've outlined below. I was also fortunate to benefit from the amazing tooling around Xcode, TestFlight, and some tedious processes like contacting the U.S. Department of Commerce.

📱 Building User Interfaces with SwiftUI

When I first saw SwiftUI during its introduction at WWDC 2019, I immediately thought of similar tools in web development, especially React and the influence it might have had when SwiftUI was designed.

import SwiftUI

struct AboutView: View {
    var body: some View {
        VStack(spacing: 16) {
            Image(systemName: "hands.sparkles.fill")
                .aspectRatio(contentMode: .fit)
                .frame(width: 40)
            Text("Hello, World!")

Leveraging a lot of compiler magic, SwiftUI is a framework, built on top of Swift, that allows you to design and build cross-platform user interfaces for all Apple devices. Views are conceptually similar to React components, constructed from built-in Views like the Text ,Image, and VStack , which I used in the example above.

Because everything is built on top of Swift itself, you can get really creative in how you build your views, you could even do it completely programmatically. The built-in views allow building complex user interfaces while conforming to the best practices and human interface guidelines.

With the latest changes, it seems like building applications will revolve increasingly around SwiftUI while being exposed to less "low-level" code like SceneDelegates, AppDelegates, and other parts Apple has started to phase out, replacing it with a simple App protocol. From a beginner's perspective, this is great news. Less friction to getting my application running is the best that could happen.

🌗 Adaptive Colors for Automagic Dark Mode Support

Notice how I used .blue when picking a color for the icon and .headline for the label, both of those values will adapt to the current environment. If you switch to dark mode, the text color will be inverted, and everything just works. This is the magic of using semantic colors instead of fixed values.

🖼 SF Symbols are Beautiful

With the release of SF Symbols, Apple started to provide carefully-crafted icons you can use in your applications. They integrate seamlessly with system fonts, ensuring optical alignment, and adapt to vibrancy, accessibility settings, and appearance modes out of the box.

☝️ Explicit Dependencies

I quickly noticed that similar to React, SwiftUI views benefit a lot from being pure. When your app maintains a global state and complex view hierarchy, it can be tempting to pass everything down through Environments (similar to React's Context). Unfortunately, this will break your previews as they don't represent real environments, as well as making your code harder to reason about.

You can fix your previews and make your code easier to grasp in one step: Make sure your view receives all dependencies explicitly, and make sure it doesn't require more than it really needs. Those two decisions will force you to build self-contained views that are scoped to a specific purpose, then connect and compose those views to a larger system.

In the end, you should probably be able to inspect and test each of your views, without having to mock the entire application state. I think a lot of software architecture and design play into this, the problems aren't exclusive to app development. Writing testable code teaches you to prevent global state, build interfaces, and utilize dependency injection to provide what's needed.

🍭 Great Tooling Compounds Value

From the Preview feature that allows you to design and build your SwiftUI views with instant visual feedback, or the simulator for testing your application on different device types, Xcode packs a wide range of tools and features I've had the pleasure of using so far, and there's a lot more to discover!

Building and bundling up your app to be distributed to testers via TestFlight, or shipped to the App Store, is possible in a couple of clicks, while code signing and other build tasks are completely managed, so you don't have to worry about the details.

🔓 Encryption and Export Compliance

When distributing applications through the App Store, you will need to make sure to comply with U.S export laws concerning the use of encryption software. This means that as soon as your app is sending API requests over HTTPS, you're obligated to notify the U.S. government. While common forms of encryption such as TLS and most functionality built into the operating system will be exempt from export regulations, you'll still need to file an annual self-classification report to the Bureau of Industry and Security.

And that's about it for my initial experience! I'm excited to dive deep into application development, so more posts on all of those aforementioned topics will follow in due time, see you then 👋