Result Builders
Result builders power SwiftUI's declarative syntax. Learn @resultBuilder , the buildBlock / buildOptional / buildEither / buildArray methods, how @ViewBuilder and the body DSL work, and write a simple builder yourself.
Learn Result Builders in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Your First Builder
Mark the type @resultBuilder and implement buildBlock . Applying the attribute to a function turns its body into a declarative DSL.
2️⃣ Control Flow in a Builder
Add more methods to unlock control flow: buildOptional for a bare if , buildEither for if/else , and buildArray for for loops.
3️⃣ SwiftUI's @ViewBuilder
SwiftUI's body is built by @ViewBuilder . That is why you list views with no commas or return , and why if/else works inside a body.
Your turn. Fill in the defining attribute and the required method.
📋 Quick Reference
Write a builder whose buildBlock sums the numbers you list, then total three values.
Practice quiz
Which attribute defines a result builder?
- @resultBuilder
- @dsl
- @buildable
- @builder
Answer: @resultBuilder. A type becomes a result builder when marked with the @resultBuilder attribute.
Which method is required and combines the statements in a block?
- buildList
- buildAll
- buildBlock
- buildFinal
Answer: buildBlock. buildBlock(_:) is the core method that combines the components written in a block.
Which method enables an if without else inside a builder?
- buildIf
- buildOptional
- buildMaybe
- buildEither
Answer: buildOptional. buildOptional(_:) handles an if statement that may produce no value.
Which method handles the two branches of an if/else?
- buildBranch
- buildSwitch
- buildChoice
- buildEither(first:)/buildEither(second:)
Answer: buildEither(first:)/buildEither(second:). buildEither(first:) and buildEither(second:) handle the two branches of if/else and switch.
Which method supports a for loop inside the builder?
- buildArray
- buildEach
- buildLoop
- buildFor
Answer: buildArray. buildArray(_:) combines the results produced by iterating a for loop.
What is SwiftUI's @ViewBuilder an example of?
- A protocol
- A result builder
- A macro
- A property wrapper
Answer: A result builder. @ViewBuilder is a result builder that assembles the views listed in a body into one view.
Why doesn't a SwiftUI body need commas or return between views?
- They are stored in an array literal
- Macros remove them
- The compiler ignores them
- A result builder transforms the statements into one combined value
Answer: A result builder transforms the statements into one combined value. The result builder rewrites the listed statements into buildBlock calls, so no commas or return are needed.
Where do you attach a result builder so a closure uses it?
- Only on the type
- In a protocol only
- On a parameter, property, or function as an attribute
- Nowhere; it is automatic
Answer: On a parameter, property, or function as an attribute. You apply the builder attribute to a function, computed property, or a closure parameter to transform that block.
Which optional method post-processes the final combined result?
- buildResult
- buildFinalResult
- buildExpression
- buildLimited
Answer: buildFinalResult. buildFinalResult(_:) lets you transform the assembled value one last time before it is returned.
What does buildExpression let you do?
- Convert each individual expression into the component type
- Nothing useful
- Run the block twice
- Add commas
Answer: Convert each individual expression into the component type. buildExpression(_:) lets the builder accept raw expressions and lift them into its component type.