
Swift Language
- 2.8k installs
- 944 repo stars
- Updated July 15, 2026
- dpearson2699/swift-ios-skills
swift-language is a skill for modern Swift patterns: expressions, typed throws, @resultBuilder DSL, property wrappers, and some versus any types.
About
Swift Language Patterns covers modern Swift 6.3 language features for non-concurrency, non-SwiftUI core code including if and switch expressions, typed throws, @resultBuilder DSL, property wrappers, opaque versus existential types, guard patterns, Never type, Regex composition, basic Codable shaping, modern collection APIs, FormatStyle basics, and string interpolation. If and switch expressions assign or return values when every branch shares a type with single-expression branches only. Typed throws with throws(SomeError) enable exhaustive catch handling while throws(Never) marks functions that never throw in generic contexts. @resultBuilder enables DSL syntax with buildBlock, buildOptional, buildEither, and buildArray methods. Property wrappers expose wrappedValue and projectedValue with composition rules. Opaque some Protocol preserves static dispatch while any Protocol supports heterogeneous collections with dynamic dispatch tradeoffs. Guard patterns enforce preconditions with early exit. Deeper Codable, FormatStyle, API naming, concurrency, and SwiftUI topics route to sibling swift skills. Common mistakes and review checklist close the guidance.
- If and switch expressions for value assignment.
- Typed throws and throws(Never) error typing rules.
- @resultBuilder DSL with buildBlock and buildEither.
- some versus any protocol dispatch guidance table.
- Modern collection APIs and Codable routing notes.
Swift Language by the numbers
- 2,754 all-time installs (skills.sh)
- +120 installs in the week ending Jul 29, 2026 (Skillselion tracking)
- Ranked #46 of 782 Skill Development skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 31, 2026 (Skillselion catalog sync)
swift-language capabilities & compatibility
- Capabilities
- if and switch expression assignment patterns · typed throws and throws(never) guidance · custom @resultbuilder dsl construction · property wrapper design with projected values · some versus any protocol selection rules · routing to swift codable and swiftui sibling ski
- Use cases
- refactoring · code review
- Pricing
- Free
What swift-language says it does
Every branch must produce a value of the same type.
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill swift-languageAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.8k |
|---|---|
| repo stars | ★ 944 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 15, 2026 |
| Repository | dpearson2699/swift-ios-skills ↗ |
How do I write idiomatic modern Swift for generics, enums, and language features outside SwiftUI?
Apply modern Swift language patterns for expressions, typed throws, @resultBuilder DSL, and collection APIs outside concurrency UI.
Who is it for?
Developers writing core Swift logic involving generics, protocols, enums, and modern syntax.
Skip if: Skip for deep Codable decoding, detailed FormatStyle, or SwiftUI state routing to sibling skills.
When should I use this skill?
User writes Swift with if expressions, typed throws, @resultBuilder DSL, or some versus any protocol choices.
What you get
Correct expression syntax, typed error handling, and protocol type choices with checklist-reviewed code.
- Idiomatic Swift core code
- Modern Codable and collection implementations
By the numbers
- Covers Swift 6+ typed throws and Swift 5.9+ if/switch expressions
- Includes Swift 5.7+ Regex builder patterns
Files
Swift Language Patterns
Core Swift language features and modern syntax patterns targeting Swift 6.3. Covers language constructs, type system features, basic Codable, string and collection APIs, basic formatting, C interop (@c), module disambiguation (ModuleName::symbol), and performance attributes (@specialized, @inline(always)). For @c corrections, enumerate invalid Swift-only signature types: String, Array, UnsafeBufferPointer, closures, and generic placeholders. Route deeper Codable/API decoding to swift-codable, detailed formatting/localization to swift-formatstyle, API naming to swift-api-design-guidelines, concurrency to swift-concurrency, and SwiftUI state/view work to swiftui-patterns.
Contents
- If/Switch Expressions
- Typed Throws
- Result Builders
- Property Wrappers
- Opaque and Existential Types
- Guard Patterns
- Never Type
- Regex Builders
- Codable Best Practices
- Modern Collection APIs
- FormatStyle
- String Interpolation
- Common Mistakes
- Review Checklist
- References
If/Switch Expressions
Swift 5.9+ allows if and switch as expressions that return values. Use them to assign, return, or initialize directly.
// Assign from if expression
let icon = if isComplete { "checkmark.circle.fill" } else { "circle" }
// Assign from switch expression
let label = switch status {
case .draft: "Draft"
case .published: "Published"
case .archived: "Archived"
}
// Works in return position
func color(for priority: Priority) -> Color {
switch priority {
case .high: .red
case .medium: .orange
case .low: .green
}
}Rules:
- Every branch must produce a value of the same type.
- Multi-statement branches are not allowed -- each branch is a single expression.
- Wrap in parentheses when used as a function argument to avoid ambiguity.
Typed Throws
Swift 6+ allows specifying the error type a function throws.
enum ValidationError: Error {
case tooShort, invalidCharacters, alreadyTaken
}
func validate(username: String) throws(ValidationError) -> String {
guard username.count >= 3 else { throw .tooShort }
guard username.allSatisfy(\.isLetterOrDigit) else { throw .invalidCharacters }
return username.lowercased()
}
// Caller gets typed error -- no cast needed
do {
let name = try validate(username: input)
} catch {
// error is ValidationError, not any Error
switch error {
case .tooShort: print("Too short")
case .invalidCharacters: print("Invalid characters")
case .alreadyTaken: print("Taken")
}
}Rules:
- Use
throws(SomeError)only when callers benefit from exhaustive error
handling. For mixed error sources, use untyped throws.
throws(Never)marks a function that syntactically throws but never actually
does -- useful in generic contexts.
- Typed throws propagate: a function calling
throws(A)andthrows(B)must
itself throw a type that covers both (or use untyped throws).
Result Builders
@resultBuilder enables DSL-style syntax. SwiftUI's @ViewBuilder is the most common example, but you can create custom builders for any domain.
@resultBuilder
struct ArrayBuilder<Element> {
static func buildBlock(_ components: [Element]...) -> [Element] {
components.flatMap { $0 }
}
static func buildExpression(_ expression: Element) -> [Element] { [expression] }
static func buildOptional(_ component: [Element]?) -> [Element] { component ?? [] }
static func buildEither(first component: [Element]) -> [Element] { component }
static func buildEither(second component: [Element]) -> [Element] { component }
static func buildArray(_ components: [[Element]]) -> [Element] { components.flatMap { $0 } }
}
func makeItems(@ArrayBuilder<String> content: () -> [String]) -> [String] { content() }
let items = makeItems {
"Always included"
if showExtra { "Conditional" }
for name in names { name.uppercased() }
}Builder methods: buildBlock (combine statements), buildExpression (single value), buildOptional (if without else), buildEither (if/else), buildArray (for..in), buildFinalResult (optional post-processing).
Property Wrappers
Custom @propertyWrapper types encapsulate storage and access patterns.
@propertyWrapper
struct Clamped<Value: Comparable> {
private var value: Value
let range: ClosedRange<Value>
var wrappedValue: Value {
get { value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
var projectedValue: ClosedRange<Value> { range }
init(wrappedValue: Value, _ range: ClosedRange<Value>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
}
// Usage
struct Volume {
@Clamped(0...100) var level: Int = 50
}
var v = Volume()
v.level = 150 // clamped to 100
print(v.$level) // projected value: 0...100Design rules:
wrappedValueis the primary getter/setter.projectedValue(accessed via$property) provides metadata or bindings.- Property wrappers can be composed:
@A @B var xapplies outer wrapper first. - Do not use property wrappers when a simple computed property suffices.
Opaque and Existential Types
some Protocol (Opaque Type)
The caller does not know the concrete type, but the compiler does. The underlying type is fixed for a given scope.
func makeCollection() -> some Collection<Int> {
[1, 2, 3] // Always returns Array<Int> -- compiler knows the concrete type
}Use some for:
- Return types when you want to hide implementation but preserve type identity.
- Parameter types (Swift 5.7+):
some Pis shorthand for an unnamed generic
parameter such as <T: P>.
any Protocol (Existential Type)
An existential box that can hold any conforming type at runtime. It uses dynamic dispatch and may allocate when the value does not fit in the inline buffer.
func process(items: [any StringProtocol]) {
for item in items {
print(item.uppercased())
}
}When to choose
Use some | Use any |
|---|---|
| Return type hiding concrete type | Heterogeneous collections |
| Function parameters (replaces simple generics) | Dynamic type erasure needed |
| Better performance (static dispatch) | Protocol has Self or associated type requirements you need to erase |
Rule of thumb: Default to some. Use any only when you need a heterogeneous collection or runtime type flexibility.
Guard Patterns
guard enforces preconditions and enables early exit. It keeps the happy path left-aligned and reduces nesting.
func processOrder(_ order: Order?) throws -> Receipt {
// Unwrap optionals
guard let order else { throw OrderError.missing }
// Validate conditions
guard order.items.isEmpty == false else { throw OrderError.empty }
guard order.total > 0 else { throw OrderError.invalidTotal }
// Boolean checks
guard order.isPaid else { throw OrderError.unpaid }
// Pattern matching
guard case .confirmed(let date) = order.status else {
throw OrderError.notConfirmed
}
return Receipt(order: order, confirmedAt: date)
}Best practices:
- Use
guardfor preconditions,iffor branching logic. - Combine related guards:
guard let a, let b else { return }. - The
elseblock must exit scope:return,throw,continue,break, or
fatalError().
- Use shorthand unwrap:
guard let value else { ... }(Swift 5.7+).
Never Type
Never is an uninhabited type for code paths that never produce a value. It works as Swift's bottom type in expression contexts, but it does not implicitly conform to arbitrary protocols or satisfy a generic T: SomeProtocol constraint. When recommending Result<T, Never> or throws(Never), explicitly state all three points: uninhabited, bottom-like, and no universal protocol conformance.
// Function that terminates the program
func crashWithDiagnostics(_ message: String) -> Never {
let diagnostics = gatherDiagnostics()
logger.critical("\(message): \(diagnostics)")
fatalError(message)
}
enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
}
// Result<String, Never> -- a result that can never fail
// Exhaustive switch: no default needed since Never has no cases
func handle(_ result: Result<String, Never>) {
switch result {
case .success(let value): print(value)
// No .failure case needed -- compiler knows it's impossible
}
}Regex Builders
Swift 5.7+ Regex builder DSL provides compile-time checked, readable patterns.
import Foundation
import RegexBuilder
// Parse "2024-03-15" into components
let dateRegex = Regex {
Capture { /\d{4}/ }; "-"; Capture { /\d{2}/ }; "-"; Capture { /\d{2}/ }
}
if let match = "2024-03-15".firstMatch(of: dateRegex) {
let (_, year, month, day) = match.output
_ = (year, month, day)
}
// TryCapture with transform
let priceRegex = Regex {
"$"
TryCapture { OneOrMore(.digit); "."; Repeat(.digit, count: 2) }
transform: { Decimal(string: String($0)) }
}When to use builder vs. literal:
- Builder: complex patterns, reusable components, strong typing on captures.
- Literal (
/pattern/): simple patterns, familiarity with regex syntax. - Both can be mixed: embed
/.../literals inside builder blocks.
Codable Best Practices
Custom CodingKeys
Rename keys without writing a custom decoder:
struct User: Codable {
let id: Int
let displayName: String
let avatarURL: URL
enum CodingKeys: String, CodingKey {
case id
case displayName = "display_name"
case avatarURL = "avatar_url"
}
}Custom Decoding
Handle mismatched types, defaults, and transformations:
struct Item: Decodable {
let name: String
let quantity: Int
let isActive: Bool
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
quantity = try container.decodeIfPresent(Int.self, forKey: .quantity) ?? 0
if let boolValue = try? container.decode(Bool.self, forKey: .isActive) {
isActive = boolValue
} else {
isActive = (try container.decode(String.self, forKey: .isActive)).lowercased() == "true"
}
}
enum CodingKeys: String, CodingKey { case name, quantity; case isActive = "is_active" }
}Nested Containers
Flatten nested JSON into a flat Swift struct:
// JSON: { "id": 1, "metadata": { "created_at": "...", "tags": [...] } }
struct Record: Decodable {
let id: Int
let createdAt: String
let tags: [String]
enum CodingKeys: String, CodingKey {
case id, metadata
}
enum MetadataKeys: String, CodingKey {
case createdAt = "created_at"
case tags
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
let metadata = try container.nestedContainer(
keyedBy: MetadataKeys.self, forKey: .metadata)
createdAt = try metadata.decode(String.self, forKey: .createdAt)
tags = try metadata.decode([String].self, forKey: .tags)
}
}See references/swift-patterns-extended.md for additional Codable patterns (enums with associated values, date strategies, unkeyed containers).
Modern Collection APIs
Prefer these modern APIs over manual loops:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
// count(where:) -- use instead of .filter { }.count
let evenCount = numbers.count(where: { $0.isMultiple(of: 2) })
// contains(where:) -- short-circuits on first match
let hasNegative = numbers.contains(where: { $0 < 0 })
// first(where:) / last(where:)
let firstEven = numbers.first(where: { $0.isMultiple(of: 2) })
// String replacing() -- Swift 5.7+, returns new string
let cleaned = rawText.replacing(/\s+/, with: " ")
let snakeCase = name.replacing("_", with: " ")
// compactMap -- unwrap optionals from a transform
let ids = strings.compactMap { Int($0) }
// flatMap -- flatten nested collections
let allTags = articles.flatMap(\.tags)
// Dictionary(grouping:by:)
let byCategory = Dictionary(grouping: items, by: \.category)
// reduce(into:) -- efficient accumulation
let freq = words.reduce(into: [:]) { counts, word in
counts[word, default: 0] += 1
}FormatStyle
Use .formatted() instead of DateFormatter/NumberFormatter. It is type-safe, localized, and concise.
// Dates
let now = Date.now
now.formatted() // "3/15/2024, 2:30 PM"
now.formatted(date: .abbreviated, time: .shortened) // "Mar 15, 2024, 2:30 PM"
now.formatted(.dateTime.year().month().day()) // "Mar 15, 2024"
now.formatted(.relative(presentation: .named)) // "yesterday"
// Numbers
let price = 42.5
price.formatted(.currency(code: "USD")) // "$42.50"
price.formatted(.percent) // "4,250%"
(1_000_000).formatted(.number.notation(.compactName)) // "1M"
// Measurements
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
distance.formatted(.measurement(width: .abbreviated)) // "5 km"
// Duration (Swift 5.7+)
let duration = Duration.seconds(3661)
duration.formatted(.time(pattern: .hourMinuteSecond)) // "1:01:01"
// Byte counts
Int64(1_500_000).formatted(.byteCount(style: .file)) // "1.5 MB"
// Lists
["Alice", "Bob", "Carol"].formatted(.list(type: .and)) // "Alice, Bob, and Carol"Parsing: FormatStyle also supports parsing:
let value = try Decimal("$42.50", format: .currency(code: "USD"))
let date = try Date("Mar 15, 2024", strategy: .dateTime.month().day().year())String Interpolation
Extend DefaultStringInterpolation for domain-specific formatting. Use """ for multi-line strings (indentation is relative to the closing """). See references/swift-patterns-extended.md for custom interpolation examples.
Common Mistakes
1. Using `any` when `some` works. Default to some for return types and parameters. any has runtime overhead and loses type information. 2. Manual loops instead of collection APIs. Use count(where:), contains(where:), compactMap, flatMap instead of manual iteration. 3. `DateFormatter` instead of FormatStyle. .formatted() is simpler, type-safe, and handles localization automatically. 4. Force-unwrapping Codable decodes. Use decodeIfPresent with defaults for optional or missing keys. 5. Nested if-let chains. Use guard let for preconditions to keep the happy path at the top level. 6. Invalid `@c` signatures. Name valid C types and explicitly reject: String, Array, UnsafeBufferPointer, closures, generic placeholders. 7. Ignoring typed throws. When a function has a single, clear error type, typed throws give callers exhaustive switch without casting. 8. Overusing property wrappers. A computed property is simpler when there is no reuse or projected value needed. 9. Underspecifying `Never`. For Result<T, Never> or throws(Never), say: uninhabited, bottom-like, and not arbitrary T: P protocol conformance. 10. Owning deep formatting/localization. Use swift-formatstyle for detailed formatting and ios-localization for market/localized-display QA.
Review Checklist
- [ ]
someused for opaque returns and Swift 5.7+ generic-parameter shorthand - [ ]
guardfor preconditions; collection APIs instead of manual loops - [ ]
.formatted()used instead ofDateFormatter/NumberFormatter - [ ] Codable types use
CodingKeysfor API mapping;decodeIfPresentwith defaults for optional fields - [ ] if/switch expressions for conditional assignment; property wrappers have clear reuse justification
- [ ] Regex builder used for complex patterns (literal OK for simple ones)
- [ ] Typed throws used when callers benefit from exhaustive error handling
- [ ]
@ccorrections enumerate rejected Swift-only types by name - [ ]
Neverguidance says uninhabited, bottom-like, and not arbitraryT: Pprotocol conformance - [ ] deep Codable, formatting/localization, naming, concurrency, and SwiftUI work routed to sibling skills
References
- Extended patterns and Codable examples: references/swift-patterns-extended.md
- Attributes and C interop: references/swift-attributes-interop.md
{
"skill_name": "swift-language",
"evals": [
{
"id": 0,
"name": "modern-language-refactor",
"prompt": "Review and modernize this Swift helper without changing behavior. Use current Swift language idioms where they help, but keep the answer concise.\n\n```swift\nenum Priority { case low, normal, high }\nenum ValidationError: Error { case empty, tooLong }\n\nfunc validateTitle(_ title: String) throws -> String {\n if title.isEmpty {\n throw ValidationError.empty\n }\n if title.count > 80 {\n throw ValidationError.tooLong\n }\n return title.trimmingCharacters(in: .whitespacesAndNewlines)\n}\n\nfunc iconName(priority: Priority) -> String {\n var name = \"circle\"\n switch priority {\n case .low:\n name = \"arrow.down.circle\"\n case .normal:\n name = \"circle\"\n case .high:\n name = \"exclamationmark.circle\"\n }\n return name\n}\n\nfunc summarize(_ tags: [String]) -> String {\n var urgentCount = 0\n for tag in tags {\n if tag == \"urgent\" { urgentCount += 1 }\n }\n return \"urgent: \\(urgentCount)\"\n}\n```",
"expected_output": "A concise modernization that uses guard preconditions, typed throws for the single validation error domain, switch expressions for conditional return, collection APIs such as count(where:), and explains why each change is appropriate.",
"files": [],
"assertions": [
"Uses `throws(ValidationError)` or explicitly recommends typed throws for the single validation error domain.",
"Uses `guard` for validation preconditions in `validateTitle(_:)`.",
"Rewrites `iconName(priority:)` with a `switch` expression or equivalent single-expression return without a mutable temporary variable.",
"Uses `count(where:)` rather than a manual loop for counting urgent tags.",
"Keeps the answer focused on Swift language idioms and does not expand into SwiftUI, concurrency, or lint configuration."
]
},
{
"id": 1,
"name": "swift63-interop-attributes",
"prompt": "Correct this Swift 6.3 interoperability/performance note for a team wiki. The draft says: `@c func export(_ bytes: UnsafeBufferPointer<UInt8>) -> Int32` is valid C export syntax, `@specialize` is the official function-specialization attribute, `@inline(always)` is just a hint, and module selectors are written `ModuleName.symbol`.\n\nGive a corrected note with minimal Swift examples.",
"expected_output": "A source-grounded correction that uses a C-compatible @c signature, names @specialized as the official explicit-specialization attribute, treats @inline(always) as a guaranteed inlining request that can fail when impossible, and uses ModuleName::symbol module selectors.",
"files": [],
"assertions": [
"Rejects `UnsafeBufferPointer<UInt8>` in an `@c` exported function signature because it is a Swift struct, not a C-representable parameter.",
"Shows an `@c` example using C-compatible pointer and scalar types, optionally with a custom C symbol name.",
"Uses `@specialized`, not `@specialize`, for explicit specialization.",
"States that Swift 6.3 `@inline(always)` guarantees inlining for direct calls and can produce an error when inlining is impossible.",
"Uses `ModuleName::symbol` syntax for module selectors."
]
},
{
"id": 2,
"name": "sibling-boundary-routing",
"prompt": "I have three cleanup requests in an iOS package: build full Codable API models with snake_case key strategies and date decoding, design locale-sensitive currency/date/list formatting for several markets, and decide whether a reusable Swift helper should use `some`, `any`, or `Never`. Which parts should the Swift language skill own, and which should be routed to sibling skills? Include only minimal examples.",
"expected_output": "A boundary-aware routing answer that keeps swift-language focused on core type-system features such as some/any/Never, routes deep Codable/API decoding to swift-codable, routes detailed formatting and localization-sensitive display work to swift-formatstyle or ios-localization, and avoids implementing the sibling domains.",
"files": [],
"assertions": [
"Says swift-language owns the core type-system/language decision around `some`, `any`, and `Never`.",
"Correctly explains that `Never` is uninhabited/bottom-type-like in expression contexts but does not implicitly conform to arbitrary protocols.",
"Routes full Codable API model design, key strategies, and date decoding to `swift-codable`.",
"Routes detailed FormatStyle and locale-sensitive display work to `swift-formatstyle` and mentions localization review when appropriate.",
"Does not provide a full Codable model suite or full formatting/localization implementation."
]
}
]
}
Swift Attributes and C Interoperability
Attributes and interoperability features for Swift. Covers C-calling-convention export, module disambiguation, performance annotations, and symbol visibility control.
Contents
- C Interoperability — `@c` Attribute
- Module Selectors
- Performance Annotations
- Symbol Visibility and Layout
C Interoperability — @c Attribute
The @c attribute (SE-0495) marks a Swift function for direct C-calling-convention export. The function becomes callable from C, C++, and Objective-C without bridging headers or @_cdecl.
@c(MyLib_processBuffer)
public func processBuffer(_ buffer: UnsafePointer<UInt8>?, _ count: Int32) -> Int32 {
guard let buffer else { return 0 }
return buffer.pointee == 0 ? 0 : count
}Requirements:
- Parameters and return types must be C-compatible (primitives, pointers, tuples of C-compatible types)
- No Swift-only types (
String,Array,UnsafeBufferPointer, closures, generic placeholders, etc.) in the signature - The function must be a module-level free function (not a method)
- Use
@c(CustomName)when the C symbol should differ from the Swift function name
Module Selectors
SE-0491 adds ModuleName::symbolName syntax to disambiguate identically named symbols from different modules without import aliasing.
import NetworkingA
import NetworkingB
// Both modules export a top-level `configure()` function
func setup() {
NetworkingA::configure()
NetworkingB::configure()
}
// Works with types too
let client: NetworkingA::Client = .init()Performance Annotations
@specialized
SE-0460 makes @specialized an official attribute (previously underscored as @_specialize). Forces the compiler to emit a specialized version of a generic function for specific concrete types.
@specialized(where T == Int)
@specialized(where T == Double)
func sum<T: Numeric>(_ values: [T]) -> T {
values.reduce(.zero, +)
}@inline(always) Guarantee
SE-0496 guarantees @inline(always) will inline the function at every call site. Previously it was a hint the compiler could ignore. A compilation error is now emitted if inlining is impossible (e.g., recursive calls).
@inline(always)
func fastPath(_ x: Int) -> Int {
x &+ 1 // Guaranteed to be inlined at every call site
}Symbol Visibility and Layout
@export
SE-0497 gives explicit control over symbol visibility and definition availability:
@export(interface)— ensures a callable symbol exists in the binary but hides the definition from clients (no inlining/specialization by external callers). Replaces@_neverEmitIntoClient.@export(implementation)— makes the definition available for inlining/specialization but does not guarantee a callable symbol. Replaces@_alwaysEmitIntoClient.
@export(interface)
public func stableAPI() -> Int {
// Callable symbol guaranteed; definition hidden from clients
return computeValue()
}@section and @used
SE-0492 places global variables into named binary sections and prevents dead-stripping. Primarily for Embedded Swift and systems programming.
@section(".mydata") @used
var configFlag: Int32 = 1Swift Patterns Extended Reference
Additional patterns and examples that extend the core SKILL.md. Refer to this file for deeper Codable patterns, advanced result builder techniques, and supplementary collection/formatting recipes.
Contents
- Codable: Enums with Associated Values
- Codable: Date Decoding Strategies
- Codable: Unkeyed Containers (Arrays)
- Codable: Wrapper for Lossy Array Decoding
- Codable: `@dynamicMemberLookup` Wrapper
- Result Builder: HTML Builder
- Result Builder: buildFinalResult
- Property Wrapper: UserDefaults-Backed
- Property Wrapper: Validated
- Advanced Regex Builder Patterns
- FormatStyle: Custom FormatStyle
- Collection Patterns: Chunking and Windows
- Guard: Complex Pattern Matching
- Typed Throws: Protocol with Typed Errors
- String Interpolation: Custom appendInterpolation
- Never: Advanced Usage
Codable: Enums with Associated Values
enum Shape: Codable {
case circle(radius: Double)
case rectangle(width: Double, height: Double)
enum CodingKeys: String, CodingKey {
case type, radius, width, height
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .circle(let radius):
try container.encode("circle", forKey: .type)
try container.encode(radius, forKey: .radius)
case .rectangle(let width, let height):
try container.encode("rectangle", forKey: .type)
try container.encode(width, forKey: .width)
try container.encode(height, forKey: .height)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
switch type {
case "circle":
let radius = try container.decode(Double.self, forKey: .radius)
self = .circle(radius: radius)
case "rectangle":
let width = try container.decode(Double.self, forKey: .width)
let height = try container.decode(Double.self, forKey: .height)
self = .rectangle(width: width, height: height)
default:
throw DecodingError.dataCorruptedError(
forKey: .type, in: container,
debugDescription: "Unknown shape type: \(type)")
}
}
}Codable: Date Decoding Strategies
// Configure decoder for specific date formats
let decoder = JSONDecoder()
// ISO 8601 (most common for APIs)
decoder.dateDecodingStrategy = .iso8601
// Unix timestamp (seconds since epoch)
decoder.dateDecodingStrategy = .secondsSince1970
// Custom format
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = Locale(identifier: "en_US_POSIX")
decoder.dateDecodingStrategy = .formatted(formatter)
// Multiple formats in one payload
decoder.dateDecodingStrategy = .custom { decoder in
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
let iso = ISO8601DateFormatter()
if let date = iso.date(from: string) { return date }
let fallback = DateFormatter()
fallback.dateFormat = "yyyy-MM-dd"
fallback.locale = Locale(identifier: "en_US_POSIX")
if let date = fallback.date(from: string) { return date }
throw DecodingError.dataCorruptedError(
in: container, debugDescription: "Cannot decode date: \(string)")
}Codable: Unkeyed Containers (Arrays)
// JSON: { "coordinates": [37.7749, -122.4194] }
struct Location: Decodable {
let latitude: Double
let longitude: Double
enum CodingKeys: String, CodingKey {
case coordinates
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var coords = try container.nestedUnkeyedContainer(forKey: .coordinates)
latitude = try coords.decode(Double.self)
longitude = try coords.decode(Double.self)
}
}Codable: Wrapper for Lossy Array Decoding
Skip invalid elements instead of failing the entire array:
struct LossyArray<Element: Decodable>: Decodable {
let elements: [Element]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var result: [Element] = []
while !container.isAtEnd {
if let element = try? container.decode(Element.self) {
result.append(element)
} else {
_ = try? container.decode(AnyCodable.self) // skip invalid
}
}
elements = result
}
}
private struct AnyCodable: Decodable {}Codable: @dynamicMemberLookup Wrapper
Type-safe access to arbitrary JSON:
@dynamicMemberLookup
struct JSONValue: Decodable {
private let storage: [String: Any]
subscript(dynamicMember key: String) -> JSONValue? {
guard let value = storage[key] as? [String: Any] else { return nil }
return JSONValue(storage: value)
}
func string(for key: String) -> String? {
storage[key] as? String
}
func int(for key: String) -> Int? {
storage[key] as? Int
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
guard let dict = try container.decode([String: AnyCodableValue].self)
.mapValues({ $0.value }) as? [String: Any] else {
throw DecodingError.typeMismatch(
[String: Any].self,
.init(codingPath: decoder.codingPath,
debugDescription: "Expected dictionary"))
}
storage = dict
}
}Result Builder: HTML Builder
A practical example of a custom result builder:
@resultBuilder
struct HTMLBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined(separator: "\n")
}
static func buildOptional(_ component: String?) -> String {
component ?? ""
}
static func buildEither(first component: String) -> String {
component
}
static func buildEither(second component: String) -> String {
component
}
static func buildArray(_ components: [String]) -> String {
components.joined(separator: "\n")
}
}
func div(@HTMLBuilder content: () -> String) -> String {
"<div>\n\(content())\n</div>"
}
func p(_ text: String) -> String { "<p>\(text)</p>" }
func h1(_ text: String) -> String { "<h1>\(text)</h1>" }
let html = div {
h1("Welcome")
p("Hello, world!")
if showDetails {
p("Details here")
}
}Result Builder: buildFinalResult
Transform the accumulated result at the end:
@resultBuilder
struct AttributedStringBuilder {
static func buildBlock(_ components: AttributedString...) -> AttributedString {
components.reduce(into: AttributedString()) { $0.append($1) }
}
static func buildFinalResult(_ component: AttributedString) -> Text {
Text(component)
}
}Property Wrapper: UserDefaults-Backed
@propertyWrapper
struct AppStorage<Value> {
let key: String
let defaultValue: Value
let store: UserDefaults
var wrappedValue: Value {
get { store.object(forKey: key) as? Value ?? defaultValue }
set { store.set(newValue, forKey: key) }
}
init(wrappedValue: Value, _ key: String, store: UserDefaults = .standard) {
self.key = key
self.defaultValue = wrappedValue
self.store = store
}
}
// Usage
struct Settings {
@AppStorage("onboarding_complete") var onboardingComplete = false
@AppStorage("preferred_theme") var theme = "system"
}Property Wrapper: Validated
@propertyWrapper
struct Validated<Value> {
private var value: Value
private let validator: (Value) -> Bool
private(set) var isValid: Bool
var wrappedValue: Value {
get { value }
set {
value = newValue
isValid = validator(newValue)
}
}
var projectedValue: Bool { isValid }
init(wrappedValue: Value, _ validator: @escaping (Value) -> Bool) {
self.value = wrappedValue
self.validator = validator
self.isValid = validator(wrappedValue)
}
}
// Usage
struct SignUpForm {
@Validated({ $0.count >= 3 }) var username = ""
@Validated({ $0.contains("@") && $0.contains(".") }) var email = ""
var canSubmit: Bool { $username && $email }
}Advanced Regex Builder Patterns
Reference captures with strong typing
import RegexBuilder
struct LogEntry {
let timestamp: String
let level: String
let message: String
}
let timestampRef = Reference(Substring.self)
let levelRef = Reference(Substring.self)
let messageRef = Reference(Substring.self)
let logRegex = Regex {
Capture(as: timestampRef) { /\[.+?\]/ }
" "
Capture(as: levelRef) {
ChoiceOf { "INFO"; "WARN"; "ERROR"; "DEBUG" }
}
": "
Capture(as: messageRef) { OneOrMore(.any) }
}
if let match = "[2026-05-28] INFO: Started".firstMatch(of: logRegex) {
let entry = LogEntry(
timestamp: String(match[timestampRef]),
level: String(match[levelRef]),
message: String(match[messageRef])
)
_ = entry
}Reusing regex components
let ipOctet = Regex {
ChoiceOf {
Regex { "25"; ("0"..."5") }
Regex { "2"; ("0"..."4"); .digit }
Regex { Optionally { ("0"..."1") }; .digit; Optionally { .digit } }
}
}
let ipAddress = Regex {
ipOctet; "."; ipOctet; "."; ipOctet; "."; ipOctet
}FormatStyle: Custom FormatStyle
Create reusable format styles for domain types:
struct FileSize {
let bytes: Int64
}
struct FileSizeFormatStyle: FormatStyle {
typealias FormatInput = FileSize
typealias FormatOutput = String
func format(_ value: FileSize) -> String {
ByteCountFormatter.string(fromByteCount: value.bytes, countStyle: .file)
}
}
extension FormatStyle where Self == FileSizeFormatStyle {
static var fileSize: FileSizeFormatStyle { .init() }
}
// Usage
let size = FileSize(bytes: 1_500_000)
size.formatted(.fileSize) // "1.5 MB"Collection Patterns: Chunking and Windows
// chunks(ofCount:) -- Swift Algorithms package
import Algorithms
let batches = items.chunks(ofCount: 10)
for batch in batches {
try await upload(batch)
}
// windows(ofCount:) -- sliding window
let movingAverages = values.windows(ofCount: 3).map { window in
window.reduce(0, +) / Double(window.count)
}
// adjacentPairs() -- process consecutive elements
for (previous, current) in values.adjacentPairs() {
if current > previous * 2 {
print("Spike detected")
}
}Guard: Complex Pattern Matching
func processResponse(_ data: Data) throws -> User {
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let userData = json["user"] as? [String: Any],
let name = userData["name"] as? String,
let id = userData["id"] as? Int
else {
throw ParseError.invalidFormat
}
// Use Codable instead when practical -- this is for mixed/dynamic JSON
return User(id: id, name: name)
}
// Guard with where clause
func processItems(_ items: [Item]) {
for item in items {
guard case .active(let config) = item.status,
config.isEnabled,
!config.isExpired
else { continue }
activate(item, with: config)
}
}Typed Throws: Protocol with Typed Errors
protocol DataStore {
associatedtype StoreError: Error
func save(_ data: Data) throws(StoreError)
func load(id: String) throws(StoreError) -> Data
}
struct FileStore: DataStore {
enum StoreError: Error {
case notFound, permissionDenied, diskFull
}
func save(_ data: Data) throws(StoreError) {
// ...
}
func load(id: String) throws(StoreError) -> Data {
guard fileExists(id) else { throw .notFound }
// ...
}
}String Interpolation: Custom appendInterpolation
Apple documents DefaultStringInterpolation as the type used while building interpolated strings, and supports extending it with custom appendInterpolation(...) overloads.
extension DefaultStringInterpolation {
mutating func appendInterpolation(json value: some Encodable) {
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
if let data = try? encoder.encode(value),
let string = String(data: data, encoding: .utf8) {
appendLiteral(string)
}
}
mutating func appendInterpolation(ordinal value: Int) {
let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
if let result = formatter.string(from: value as NSNumber) {
appendLiteral(result)
}
}
}
print("Config: \(json: settings)")
print("You placed \(ordinal: 3)")Never: Advanced Usage
// Publisher that never fails
let publisher: AnyPublisher<String, Never> = Just("hello").eraseToAnyPublisher()
// Phantom type preventing construction
enum Locked {}
enum Unlocked {}
struct Door<State> {
private init() {}
}
extension Door where State == Unlocked {
func open() { /* ... */ }
}
// Generic constraint meaning "this case cannot happen"
func absurd<T>(_ never: Never) -> T {
// No body needed -- Never has no values, so this is never called
}Related skills
FAQ
some or any Protocol?
Default to some for return types and parameters; use any for heterogeneous collections needing runtime erasure.
When use typed throws?
Use throws(SomeError) when callers benefit from exhaustive handling; use untyped throws for mixed sources.
Where route deep Codable?
Route detailed decoding and API naming to swift-codable and swift-api-design-guidelines skills.
Is Swift Language safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.