Friday, November 10, 2023


Tags

Declarative UI is the future.

Learning a new development language has been an incredible eye opening experience.

Friday, November 10, 2023 - Sam Rowlands

This is part 3 of my "Moving On" series. If you've been following along, you'll know that I've decided to retire from making Mac Photo apps and are in the process of leaving the tool I've used for 25 years. Read part 1 here. Read part 2 here.

Since my last post, I've been asked what language / development tool I am learning. The answer is Apple's Swift, SwiftUI and Xcode. While the Swift language is different, the biggest challenge has been learning SwiftUI as it is a Declarative UI language.

What is Declarative UI?

You write code to describe how you want the application to look and work, instead of dragging and dropping controls on a form designer.

 
 

Permissions Reset interface previews: Xcode, SwiftUI to the left. Xojo to the right. Click 'em to zoom in.

 

A macOS inspired calculator I built from scratch in an afternoon. Click to zoom in.

Describing the UI has several advantages over traditional drag-n-drop designers.

  1. Live data in the preview. In "Permissions Reset" example above, it is reading and displaying the icon and details from the file, as if the app was running. Making it easy to see how tweaks and adjustments pan out while saving time.
  2. Takes away complexities with text layout in the UI. Long labels auto-wrap and shift below controls down. Labels can be easily aligned with each other (in a number of ways). Again, saving time.
  3. Boiler plate code is added behind the scenes, providing more consistent experiences, and saving time.
  4. A single Declarative UI codebase can create apps for multiple devices and platforms.
    • SwiftUI can target Mac, iPad, iPhone, Android*, Apple Watch and Apple TV apps.
    • Google's Flutter can target Android, Android TV, Mac, Windows, Linux, iOS* and Web apps.
    • React Native can target Mac, Windows, Android, iOS*, Apple TV, Android TV and Web apps.
    • Jetpack Compose & JetBrains Compose Multiplatform can target Android, Mac, Windows, Linux, iOS and Web apps.
    • JavaFX can certainly target Mac, Windows & Linux. Marketing material says mobile, but not specifically platform
    • AvaloniaUI for .NET can target Mac, Windows, Linux, Android and iOS.

    SwiftUI Android* uses the Skip Tools transpiler to convert Swift to Kotlin.
    iOS*, I'm assuming that includes iPadOS even though I couldn't find it mentioned.

  5. Radically reduces the workload for localization, simply ensure the localized strings are in place and let UI figure it out.

    A rather crude example, showing how the button sizes adapt to the button labels.

It's not all swings and roundabouts

There is a learning curve and we're not just talking syntax, the whole paradigm is different and takes some getting used too.

There are several issues with SwiftUI.

  1. In my first week I found a 3 year old bug, that I could workaround, but I was surprised.
  2. Each year, SwiftUI gets improvements, however adopting them makes it harder to support multiple versions of the macOS.

    Thankfully Kuba Sudar has been keeping a list. macOS Apprentice from Kodeco shows how to get Xcode to tell you whats not compatible with a certain macOS version (Page 479).

  3. Missing native controls, thankfully you can fall back to AppKit, but the lack of a rich text editor is a major surprise.
  4. Some things just look wrong, take the localization example, the dialog buttons don't look right and that's because they do not meet Apple's HIG for dialog buttons without extra work.

However...

Even with the above concerns, I am excited to get deeper into SwiftUI. I honestly think this is the way forwards, yeah, it is not as easy as I hoped, but it also isn't a difficult as I feared, having a live preview really helps. So does the wealth of documentation, examples and experienced developers willing to help.

Within a few weeks, I find it frustrating to use Xojo to build a complex UI. I just want to adjust the gap between these controls... I'd like to see what it looks like if I... Tsck...