A few days ago at WWDC ’19, Apple surprised everyone with a brand-new framework called SwiftUI, which allows developers to write apps for Apple platforms using a new declarative Swift syntax, right in Xcode.

SwiftUI is built on top of Swift* and allows developers to quickly write apps without much boilerplate.

In this series, we will explore SwiftUI in more detail and learn how you can quickly get started with developing apps using this new framework.

The first few posts will be about learning the fundamentals of SwiftUI, such as spending some time understanding the syntax and basic concepts like View and ViewBuilder . The remaining posts will cover writing a simple app and going through more advanced capabilities, such as custom views, animations and interoperability with UIKit.

Let’s get started! As with any new framework, it’s important to learn the basics before trying to dive deep into it. So, we’re going to kick off this series with an introduction to some new language features in Swift 5.1 that provides us with a foundation for writing SwiftUI code.

* Technically, some parts are written in C++, such as the scenegraph which is a part of the private AttributeGraph framework, but most of the code is in fact in Swift. I suppose it makes sense to write certain performance critical code in a low level language like C++.

Part 1: The language features behind it

Part 2: The basics of views

What powers this new framework

The upcoming new languages features in Swift 5.1 plays a huge role in the development and use of SwiftUI. Without features such as opaque result types, property wrappers, function builders and dynamic replacement, it wouldn’t have been possible to build this new framework.

I have personally been following the development of these features both on Swift Evolution forums and on GitHub for several months. However, I had no clue that one of the main reasons why these features were being developed was for use in SwiftUI. I think that’s really great — all ideas that go through Swift Evolution must demonstrate that it works (implementation ready) and solves a real problem. Putting these ideas through its paces by using it in SwiftUI is certainly a great way to prove that.

Anyway, so what really are these new features and what do they do? Let’s take a look.

Opaque Result Types

Imagine we had a drawing library, which provided several primitive drawable types, such as lines and points, along with types that allow us to apply composable transformations (like joining and rotating) to these primitive types.

A drawing or painting app might use this library to define common drawable things (like shapes) in terms of this type, such as by creating a DrawableObject protocol.

However, the users of DrawableObject will now have to write long and explicit types for their drawable things.

Here, the return type of render() is extremely verbose and doesn’t really provide any useful information to the reader. The exact return type is irrelevant, all that really matters is that the return type conforms to Drawable .

Also, the fact that we’ve explicitly spelled out the return type of render() means we’re leaking implementation detail and it’s possible that clients could end up relying on this exact return type, which makes it harder for the author of Square to change how it renders the shape.

Now, you could use existentials or type-erasure to solve this problem, but it comes with its own issues, can sometimes add run-time overhead and limits the amount of type safety which the compiler can enforce at compile time, which might not always be acceptable.

So, as mentioned above, instead of spelling out the exact return type of Square.render() , we really just want to be able to say it returns a type that conforms to Drawable .

In Swift 5.1, there is now a way to do it, using the new some keyword.

This allows to declare the return type of Square.render() in terms of its capabilities (conforms to Drawable ) instead of explicitly specifying what it is. This enables us to hide the concrete implementation type of render() from the caller and allows us to change it between versions without breaking the clients of DrawableObject , as the underlying type identity is not exposed.

Basically, you can think of opaque return types as “reverse generics”. Normally, the use of generics allows the caller to choose the concrete type bound to the function’s generic parameters:

However, opaque result types can be thought of putting the generic signature on the return position of a function:

This kind of notation is a bit weird to use however, so instead we use some to convey this meaning (the opposite of this would be any — you can read more about it here).

One of the other areas where it can helpful is when the protocol has associatedtype or Self requirements. Normally, when you return such a protocol, the compiler will emit an error which many of us might have seen countless times:

By making the return type opaque to the callers, this problem vanishes:

Coming back to the topic of type identity — just like generics, the compiler has knowledge about what the underlying type is and thus can enforce several guarantees at compile-time. For example — comparing the results of two calls to the same function will always be legal. However, two calls to separate functions with the same opaque return type but different underlying types will be illegal and result in an error:

By now, you must be wondering how this feature is related to SwiftUI? Well, SwiftUI uses it to hide the concrete type of the body’s view graph, otherwise you would be leaking implementation detail and worse, you would have to spell out the return type explicitly, like below, which is not very nice!