Using Swift with WinUI on Windows

A new open-source tool from The Browser Company sets us on the road to bringing Swift apps from iOS and macOS to Windows.

shutterstock 2227591131 common Swift bird in flight over sunlit green grass
Per Grunditz / Shutterstock

You might think that Apple’s Swift is a programming language for macOS and iOS only. It’s a natural conclusion, as Swift is closely tied to Apple’s own Xcode development environment. But one part of the Swift story is often overlooked: Swift is a cross-platform programming language, with support for Linux, Android, and Windows.

Much of the confusion comes from Apple’s providing UI tooling only for its own platforms. For other platforms, Swift is intended to be a portable systems programming language, allowing you to bring business logic from mobile and desktop devices to the cloud, adding APIs for web front ends. If you want a UI, you’ll need a web browser, as there are a number of web frameworks for Swift, mainly targeting the Linux release.

Using Swift on Windows

One of the benefits of Swift as a language is that it provides a safer alternative to C, with many features from Objective C. Unlike many compiled languages, Swift supports the use of a REPL-based debugging and testing environment. You can evaluate code before compilation and use Xcode’s playgrounds to explore more complex structures. This “debug while you code” approach is intended to improve developer productivity, making debugging part of your normal flow and keeping error squashing in the context of the code you’re writing.

It’s the lack of a UI layer that makes Swift feel like a second-class citizen on Windows. If you want basic systems programming, you write a C# console app. More complex systems-level tasks usually require C++ or Rust, which Microsoft is now using in Azure.

Back to the Windows 10 ‘bridges’

While we can’t expect Swift for Windows to implement the entire macOS or iOS user experience, having some form of UI tooling would make it a lot easier to port all kinds of macOS apps and tools to Windows. Microsoft attempted something like this for Objective C, as part of its Windows 10 “bridges” project) in Project Islandwood (now an open-source project on GitHub). WinObjC, as it eventually was named, takes existing Xcode projects and converts them to Visual Studio projects, mapping common controls and services to their Windows equivalents.

Although it’s still available, WinObjC is pretty much obsolete. Beyond repository policy and documentation updates, the last major changes were made over four years ago. Both Apple’s and Microsoft’s application development strategies have changed considerably since Microsoft first delivered WinObjC, and more importantly, so have their user interface tools.

Windows App SDK and language projections

Microsoft has spent much of the last decade thinking and re-thinking its UI strategy. First there was Windows 8’s WinRT with its Metro controls. This evolved into the Windows Platform and the Windows UI Library, WinUI. As the underlying Windows development story changed, WinUI evolved with it, bringing us to WinUI 3 today. Shipping as part of the Windows App SDK, WinUI 3 offers modern controls for everywhere Windows runs.

Designed to support .NET development, the WinUI model builds on the familiar XAML foundation, separating design and layout from code. Layouts are built from controls, using a declarative language to define placement and bindings. It’s a powerful tool that works well with many different design patterns. Over time WinUI has been separated from Windows, and now updates on its own schedule, shipping as part of the Windows App SDK.

While WinUI is perhaps best known as a tool for .NET, it’s been ported to other Windows environments including C++. The C++ WinRT language projection provides a file header library that lets you use Windows App SDK APIs from any standards-compliant C++ compiler, like LLVM’s Clang or even GCC.

This is where Microsoft’s shift to open-source foundations shows its advantages. Tools and foundational developer technologies like WinUI can be taken, modified, and used by other companies to build and use (and share) their own derivatives, as well as to bring applications to the Windows desktop that might not otherwise get a port.

WinUI in Swift on Windows

A couple of weeks ago a tweet from Miguel De Icaza, one of the creators of the Mono project, pointed me to work being done by The Browser Company to use the CppWinRt tooling to build its own set of language projections to add WinUI support to Swift. This will let them bring their new, built-from-the-ground-up browser Arc to Windows, without needing to completely rewrite their existing Swift code.

That’s an important requirement for a small team. If all you have to change is the UI, then you don’t need to double up on core development, having to translate from one programming model to another, with the added risk of an increased attack surface. Instead, you can concentrate, like The Browser Company, on building an alternative to Chromium, Gecko, and WebKit that both keeps pace with web standards and provides users with the features and speed they expect. That requires every version for every platform to be released at the same time.

The team building the Windows version of the Arc browser has been using Swift with COM, so having language bindings based on the C++ WinRT tooling isn’t a huge step. The code needed to deliver a Windows UI with these bindings would look familiar to anyone who has built Windows applications using a modern language. The syntax is pure Swift, and the calls to add UI components to your application are very similar to those used to deliver an iOS or macOS experience.

From Swift to WinUI via WinRT

As WinUI uses WinRT interfaces, the Swift projection builds on WinRT interface definitions, translating the underlying C IDL (interface definition language) into function calls. While you could work with the API directly from Swift using its interop capabilities, it’s not practical to work that way. It’s an approach that adds complexity, rather than providing a simple route to adding a Windows UI as an alternative build for a Swift project.

By building a language projection, The Browser Company’s development team has mapped WinRT properties and methods to their Swift equivalents, including support for event handlers. The aim is to make coding against these APIs feel natural, that you’re working against native Swift APIs. That means the resulting library needs to work under the covers to resolve mismatches between the way that Windows APIs work and the ways that Swift expects them to work.

While Microsoft’s cross-platform work naturally focuses on taking Windows code to other platforms, it’s nice to see The Browser Company taking a different approach. Like Google’s work with Flutter, which brings apps built for a platform designed for Android to other operating systems, this is a step toward doing the same for iOS and macOS. It’s important to remember that the Windows App SDK is a lot more than WinUI 3, so while the resulting swift-winrt language projections are a useful tool, they are only part of what’s need to migrate iOS code to another ecosystem.

Next steps

Having a workable way of bringing Swift code out of iOS and macOS is a good thing, and being able to port it to WinUI and Windows could give developers access to another market, one that already has an app store and a set of cloud-hosted build tools that can automate the process of going from pull request to store availability.

What we need next is for someone to take the old Project Islandwood tooling, or maybe some of Xamarin’s work, and use it to integrate more Windows APIs into Swift apps, building on Swift’s Objective-C heritage. After all, they’re all open source. No matter who does it, The Browser Company’s new tooling is definite progress in building a more open, cross-platform world. It will be interesting to see where Swift on Windows goes from here.

Copyright © 2023 IDG Communications, Inc.