Logo for tanaschita.com

Understanding opaque types in Swift

Learn how to use opaque return types in Swift and SwiftUI.

07 Feb 2022 · 3 min read

Swift 5.1 introduced a new language feature called opaque types. Opaque types give us the capability to return a concrete type without having to expose it. Let's directly jump into an example to see what that means.

Let's say we have a protocol called Tea. Imagine that different kind of teas might have different identifier types like String or Int, so we add an associatedtype called Identifier.

protocol Tea {
associatedtype Identifier
var id: Identifier { get }
}

Using this protocol, we can now build concrete tea types, for example GreenTea.

struct GreenTea: Tea {
let id: String
init(id: String) {
self.id = id
}
}
Sponsorship logo
Join the FREE iOS Architect Crash Course (for a limited time!)
If you’re a mid/senior iOS developer who’s looking to improve both your skills and salary level, then join this 100% free online crash course. Hurry up because it's available only until November 27th!
Click to get it now

Now, we want to build a method, that returns the currently most popular tea from the shop. Since it might change in the future, we don't want to return a concrete tea type, so we decide to return the protocol.

func favoriteTea() -> Tea {
return GreenTea(id: "someId")
}
// Compiler error

The method above will not compile with the error Protocol Tea can only be used as a generic constraint because it has Self or associated type requirements. The compiler doesn’t preserve the type identity of the returned value when using a protocol as return type, so we cannot use the protocol this way.

And here is where an opaque type comes in handy.

func favoriteTea() -> some Tea {
return GreenTea(id: "someId")
}

As we can see above, an opaque type is defined with the some keyword. Returning an opaque type is almost like returning a protocol. In both cases, the caller cannot see the concrete type. The difference is that unlike protocols, an opaque type still refers to a specific type.

However, when using opaque return types, we cannot return different types for example depending on some other value. Which we could do with protocols without associated types.

func favoriteTea() -> some Tea {
someCondition ? GreenTea(id: "someId") : AppleTea(id: 256783)
}
// Compiler error.

This results in a the compiler error Function declares an opaque return type, but the return statements in its body do not have matching underlying types. We could still return different teas of the same concrete type though.

Opaque types in SwiftUI

You may have already noticed that SwiftUI uses opaque return types for building views.

var body: some View {
}

This way, SwiftUI prevents the exact type information of the view hierarchy to be able to do tasks like diffing. And at the same time, we don't need to specify the exact type of this view hierarchy - which can get quite complex.

When working with opaque types in SwiftUI, you may have already stumbled across the problem mentioned earlier.

private var nameView: some View {
if isEditable {
return TextField("Your name", text: $name)
} else {
return Text(name)
}
}

The above code won't compile with the error message Function declares an opaque return type, but the return statements in its body do not have matching underlying types. Solutions on how we can still build a view hierarchy with conditional statements are covered in this article on How to avoid using AnyView in SwiftUI.

Sponsorship logo
Join the FREE iOS Architect Crash Course (for a limited time!)
If you’re a mid/senior iOS developer who’s looking to improve both your skills and salary level, then join this 100% free online crash course. Hurry up because it's available only until November 27th!
Click to get it now

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

generics and protocols

swift

Understanding the some keyword when working with generic protocols in Swift 5.7

Learn about opaque parameter declarations introduced at WWDC22.

13 Jun 2022 · 2 min read

Latest articles and tips

© 2022 tanaschita.com

Privacy policy

Impressum