Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do view types like Text or Image conform to the View protocol in SwiftUI?

There is one big thing that confuses me about view types in SwiftUI:

They don't seem to conform to the View protocol, but somehow, they mysteriously do.

Take the Text type for example. It's defined as follows:

public struct Text : Equatable { ... }

I can't find any public extension that adds conformance to the View protocol, like

extension Text: View { ... }

and the Relationships section in the official documentation simply states:

Conforms To: Equatable

Nothing more, that's all.

Yet, I can return an instance of Text where some View is required, for example:

var body: some View {
    Text("I'm a View, I swear!") 
}

If Text didn't conform to View, this wouldn't be possible and throw a compiler error.

(some View is an opaque result type which means it's a specific type with an identity, but one that conforms to View.)

So how is this possible?

Where is the View protocol conformance specified for SwiftUI view types (like Text, Image, Circle, ...)?

like image 558
Mischa Avatar asked Jun 06 '19 03:06

Mischa


People also ask

How do Views work in SwiftUI?

SwiftUI builds the view hierarchy of a View by calling the body property to initialise its children. It will then call the body property of each of those children, which may then initialise their own children, which have their body property called, and so on.

What data structure does SwiftUI use for views?

SwiftUI does not: we prefer to use structs for views across the board, and there are a couple of reasons why. First, there is an element of performance: structs are simpler and faster than classes.

What is view protocol in Swift?

The View protocol provides a set of modifiers — protocol methods with default implementations — that you use to configure views in the layout of your app. Modifiers work by wrapping the view instance on which you call them in another view with the specified characteristics, as described in Configuring views.

Is text a view in SwiftUI?

Text in SwiftUI is a view that lets you display one or more lines of text. This is suitable for read-only information that's not editable. To display a line of text, you initialize Text and set a String value.


1 Answers

This question was asked on June 6, 2019, during WWDC, when we only had the first beta of Xcode 11 and SwiftUI. So answering this question correctly requires access to that version of SwiftUI. You can download Xcode 11 beta 1 here. (Thank you, xcodereleases.com!) You are in for an adventure trying to unpack the archive, though, because (I think) it was signed with a certificate that has since expired. I resorted to black magic (stepping through the xip command in LLDB and modifying memory at a key moment to subvert the certificate verification). You could perhaps just set your system time back to June 6, 2019 before unpacking.

Anyway, here's the secret to understanding why Text didn't appear to conform to View: Xcode, and Apple's documentation generator, intentionally omit identifiers in the SDK that start with _.

So if you want to see the full public declaration of a type, you cannot rely on Xcode or the documentation to show it to you. Instead, you have to dig up the .swiftinterface file for the module. For SwiftUI, you can find it here, relative to the Xcode.app directory:

Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64.swiftinterface

In the Xcode 11 beta 1 version of that file, you won't find a direct conformance Text: View. Instead, you will find this:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension Text : _UnaryView {
  public static func _makeView(view: _GraphValue<Text>, inputs: _ViewInputs) -> _ViewOutputs
  public typealias Body = Swift.Never
}

And you will find that _UnaryView is a sub-protocol of View:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol _UnaryView : SwiftUI.View where Self.Body : SwiftUI._UnaryView {
}

So, in Xcode 11 beta 1 and the corresponding iOS, macOS, tvOS, and watchOS betas, Text conforms to View indirectly, through its conformance to _UnaryView. Since _UnaryView is part of the SDK and begins with _, Xcode and the Apple documentation hide that symbol. So you can't see the conformance through normal methods.

At some later point (but still, I believe, during the Xcode 11.0 beta period), Apple eliminated the _UnaryView protocol and made Text conform directly to View. So if you check the SwiftUI .swiftinterface file in Xcode 11.4 (the current version as I write this), you'll find this:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension Text : SwiftUI.View {
  public static func _makeView(view: SwiftUI._GraphValue<SwiftUI.Text>, inputs: SwiftUI._ViewInputs) -> SwiftUI._ViewOutputs
  public typealias Body = Swift.Never
}
like image 58
rob mayoff Avatar answered Nov 15 '22 22:11

rob mayoff