- Published on
> Understanding the "some" Keyword in Swift and SwiftUI
- Authors

- Name
- Mick MacCallum
- @0x7fs
If you've written any SwiftUI code, you've seen some View everywhere. That some keyword might seem mysterious at first, but it solves a real problem in Swift's type system. Understanding it will help you write better SwiftUI code and make sense of compiler errors when they appear.
The Problem some Solves
Swift is a strongly typed language. Every function needs to declare what type it returns. Consider a function that returns a View:
func makeGreeting() -> Text {
Text("Hello, World!")
}
This works fine because Text is a concrete type. But what if you want to add a modifier?
func makeGreeting() -> ??? {
Text("Hello, World!")
.padding()
.background(Color.blue)
}
What's the return type? It's actually something like ModifiedContent<ModifiedContent<Text, _PaddingLayout>, _BackgroundStyleModifier<Color>>. These nested generic types quickly become unmanageable, and some of them are private implementation details you can't even reference.
Opaque Return Types
The some keyword creates an opaque return type. It tells the compiler "this function returns a specific concrete type that conforms to this protocol, but I don't want to spell out exactly what that type is."
func makeGreeting() -> some View {
Text("Hello, World!")
.padding()
.background(Color.blue)
}
The compiler knows exactly what type is being returned—it just doesn't expose that information to the caller. This is different from returning a protocol type directly:
// This returns "some concrete type conforming to View"
func makeView() -> some View {
Text("Hello")
}
// This returns "any type conforming to View" (existential)
func makeView() -> any View {
Text("Hello")
}
The difference matters for performance and type safety. With some, the compiler knows the exact type at compile time and can optimize accordingly. With any, the type is boxed in an existential container with runtime overhead.
Why SwiftUI Requires some View
SwiftUI's View protocol has an associated type called Body:
protocol View {
associatedtype Body: View
var body: Self.Body { get }
}
Protocols with associated types can't be used directly as return types without some or any. When you write var body: some View, you're telling Swift that body returns a specific view type that the compiler can figure out from the implementation.
Consistency Matters
Opaque return types require consistency. This code won't compile:
func makeView(showTitle: Bool) -> some View {
if showTitle {
return Text("Title") // Returns Text
} else {
return Image(systemName: "star") // Returns Image
}
}
Both branches return different types, but some View promises a single concrete type. The fix is to use a type-erasing container or a conditional modifier:
// Option 1: Use @ViewBuilder
@ViewBuilder
func makeView(showTitle: Bool) -> some View {
if showTitle {
Text("Title")
} else {
Image(systemName: "star")
}
}
// Option 2: Wrap in Group
func makeView(showTitle: Bool) -> some View {
Group {
if showTitle {
Text("Title")
} else {
Image(systemName: "star")
}
}
}
The @ViewBuilder attribute enables SwiftUI's result builder syntax, which automatically wraps conditional views in the appropriate container type.
some vs any
Swift 5.7 introduced any for existential types, making the distinction clearer:
// Opaque type - compiler knows the concrete type
func makeSomeView() -> some View {
Text("Hello")
}
// Existential type - type is erased at runtime
func makeAnyView() -> any View {
Text("Hello")
}
Use some when you can—it's more efficient and enables better type checking. Use any when you need to store heterogeneous types or when the concrete type genuinely varies at runtime.
Primary Associated Types
Swift 5.7 also introduced primary associated types, which you'll see with collections:
func numbers() -> some Collection<Int> {
[1, 2, 3, 4, 5]
}
This returns "some collection of integers" without specifying whether it's an Array, Set, or other collection type. The caller knows it's a collection of Int values, which is often all they need.
When You'll See Compiler Errors
Common situations where the some keyword causes confusion:
If you forget some, you'll see an error about protocols with associated types:
// Error: Protocol 'View' can only be used as a generic constraint
var body: View {
Text("Hello")
}
If you return different types from branches:
// Error: Function declares an opaque return type, but the return statements
// in its body do not have matching underlying types
If you try to store an opaque type in a variable without type inference:
// This works - type is inferred
let view = makeGreeting()
// This doesn't work - can't use 'some' for stored properties
let view: some View = makeGreeting() // Only works in certain contexts
Practical Usage
In day-to-day SwiftUI development, you'll mostly use some View for your view body properties and helper methods that return views. The type system handles the complexity behind the scenes:
struct ProfileCard: View {
let name: String
let title: String
var body: some View {
VStack(alignment: .leading) {
headerSection
Divider()
detailsSection
}
.padding()
.background(.regularMaterial)
.cornerRadius(12)
}
private var headerSection: some View {
Text(name)
.font(.headline)
}
private var detailsSection: some View {
Text(title)
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
Each computed property returns some View, keeping the actual types hidden while still being fully type-safe. The compiler ensures everything fits together correctly, and you don't have to think about the nested generic types being created.
// Continue_Learning
Using Failable Initializers to Handle Optionals in SwiftUI Views
Failable initializers offer a cleaner alternative to if-let statements when your SwiftUI views depend on optional data.
How to Access the App Delegate in Swift
Learn how to access your app's App Delegate from anywhere in your Swift code, including from SwiftUI views.
Supporting Dark Mode in a SwiftUI App
Learn how to properly support dark mode in SwiftUI using semantic colors, adaptive color assets, and color scheme detection.
// Stay Updated
Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.