Swift Evolution Monthly: May-November 2024
Discover the latest Swift updates, from Objective-C compatibility improvements to metatype keypaths, trailing commas, and new compiler controls—plus a must-have app for tracking proposals!
Swift’s GitHub repositories have officially moved from the Apple organization to the new swiftlang
organization during the summer, signaling a significant step in Swift’s evolution as a community-driven language. Meanwhile, Swift 6 brought major advances in concurrency and data-race safety. But since those changes are already well-documented in other places, I will skip the concurrency topic and focus on other improvements to Swift that are around the corner.
Looking ahead, Swift’s evolution isn’t just about concurrency. Ongoing efforts, such as the proposed Vision document for Strictly-Safe Swift, are expanding the language’s capabilities beyond app development, particularly in embedded systems or system-level programming. That said, this newsletter remains grounded in what matters most to app developers. So let's dive in!
Accepted Proposal Summaries
SE-0436: Objective-C implementations in Swift
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
A new syntax allows implementing Objective-C headers in Swift while maintaining full backward compatibility. This is particularly valuable when modernizing existing iOS apps with Swift while keeping Objective-C compatibility:
// MyView.h
@interface MyView : UIView
@property (nonatomic) CGFloat cornerRadius;
- (void)animate;
@end
// MyView.swift
@objc @implementation extension MyView {
var cornerRadius: CGFloat = 0 {
didSet { layer.cornerRadius = cornerRadius }
}
func animate() {
// Swift implementation that's fully compatible with Objective-C
}
}
This bridges the gap between modern Swift development and legacy Objective-C code, making gradual migration easier. While most relevant for teams maintaining Objective-C codebases, it's useful for any iOS developer working with mixed codebases or third-party Objective-C frameworks. And certainly Apple system engineers modernizing old system frameworks using Swift.
SE-0438: Metatype Keypaths
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
This proposal allows keypath expressions to access static properties in Swift, introducing metatype keypaths using the .Type
syntax.
Here's a practical example of how it simplifies code, especially when working with databases or property wrappers:
struct User {
static let tableName = "users"
static let primaryKey = "id"
}
// Before: Required workarounds or verbose syntax
let table = database.table(named: User.tableName)
// After: Can use keypaths directly
let tableKeyPath = \User.Type.tableName
let table = database[keyPath: tableKeyPath]
This is a moderate improvement that will be particularly valuable for developers working with frameworks that use keypaths extensively (like SwiftData or other database layers) and those building property wrapper-based systems. While not revolutionary, it removes an annoying limitation that required developers to create workarounds for accessing static properties through keypaths.
Now, we're just missing Enum Case Keypaths – I hope we get them soon!
SE-0439: Allow trailing comma in comma-separated lists
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
This proposal extends Swift's existing trailing comma support (currently limited to arrays and dictionaries) to all comma-separated lists that have clear terminators, like function parameters, tuples, and conditional statements.
Here's a practical example showing how it improves code maintenance, especially with version control:
func fetchUser(
id: String,
includeDetails: Bool = true,
cachePolicy: CachePolicy = .default, // Adding/removing parameters is now cleaner
) {
// ...
}
let coordinates = (
latitude: 37.7749,
longitude: -122.4194,
) // Better diffs when modifying values
This is a small but meaningful quality-of-life improvement that will be particularly appreciated by developers working on large codebases where code formatting and version control cleanliness are important. It reduces noise in git diffs and makes code reorganization smoother. Nice to see these kinds of improvements!
SE-0443: Precise Control Flags over Compiler Warnings
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
Swift adds granular control over compiler warnings, allowing developers to selectively upgrade warnings to errors or keep certain warnings as warnings. This is particularly valuable when maintaining large codebases:
// See which group a warning belongs to
swiftc -print-diagnostic-groups MyApp.swift
// Treat all warnings as errors except deprecations
swiftc -warnings-as-errors -Wwarning deprecated MyApp.swift
// Only make API availability warnings into errors
swiftc -Werror availability MyApp.swift
This feature helps teams maintain strict code quality while being pragmatic about certain warning categories. For example, you can enforce strict handling of memory management warnings while allowing time to address deprecation warnings during major version upgrades. It's especially useful when upgrading to new Swift versions or SDK releases that introduce new deprecations.
A drag & drop translator for String Catalog files – it's really easy.
Get it now to machine-translate your app to up to 150 languages!
SE-0444: Member import visibility
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
Did you ever notice that you could access extensions from third-party Swift packages you didn't even import in a given Swift file? While you always needed to import a module to use its types, extensions on existing types like String were silently available through transitive imports. Here's why that's problematic:
// Without importing GroceryKit, its extensions are still available
import RecipeKit
let recipe = "ingredients...".parse() // Ambiguous if GroceryKit adds parse()!
// The fix: Extensions need explicit imports
import RecipeKit
let recipe = "ingredients...".parse() // Unambiguous - only sees RecipeKit's parse()
This proposal fixes this inconsistency in Swift's module system by making extension methods follow the same visibility rules as types. Due to the breaking change nature (you may need a lot more imports), it will initially be available behind the MemberImportVisibility
compiler flag before becoming the default behavior in a future Swift version.
SE-0445: Improving String.Index
's printed descriptions
Links: 📝 Proposal | 💬 Review | ✅ Acceptance
A quality-of-life improvement coming in Swift 6.1 that makes debugging string operations easier by giving String.Index
values more meaningful descriptions:
let text = "👋🏼 Hello"
// Before: Cryptic output
print(text.firstRange(of: "el")!)
// Index(_rawBits: 655623)..<Index(_rawBits: 852487)
// After: Clear position information
print(text.firstRange(of: "el")!)
// 6[utf8]..<8[utf8]
This is a small but useful enhancement that will particularly benefit developers working on text processing code or debugging string-related issues.
Other Accepted Proposals
- SE-0441: Formalize ‘language mode’ terminology
📝 Proposal | 💬 Review | ✅ Acceptance - SE-0442: Allow TaskGroup's ChildTaskResult Type To Be Inferred
📝 Proposal | 💬 Review | ✅ Acceptance - SE-0446: Nonescapable Types
📝 Proposal | 💬 Review | ✅ Acceptance - SE-0447: Span: Safe Access to Contiguous Storage
📝 Proposal | 💬 Review | ✅ Acceptance - SE-0448: Regex lookbehind assertions
📝 Proposal | 💬 Review | ✅ Acceptance - SE-0449: Allow
nonisolated
to prevent global actor inference
📝 Proposal | 💬 Review | ✅ Acceptance
Proposals in Progress
- SE-0450: Package traits
📝 Proposal | 💬 Review - SE-0451: Raw identifiers
📝 Proposal | 💬 Review - SE-0452: Integer Generic Parameters
📝 Proposal | 💬 Review - SE-0453: Vector, a fixed-size array
📝 Proposal | 💬 Review
Noteworthy Active Threads
- Multi-statement if/switch/do expressions
- Add license info to SwiftPM & expose to projects
- Language Mode Compiler Condition
- Custom Coding Path for Codable with Swift Macro
- Improved error handling in unstructured Task initializers
- Proposal for Enhanced Enum Pattern Matching Syntax in Swift
- Introducing do-let-catch for Cleaner Error Handling
- Backtick-delimited identifiers that allow more characters
- Modify and read accessors
- Task Naming API
Other News
Before wrapping up, I want to highlight Proposal Monitor by Victor Martins—a perfect companion for anyone wanting to dive deeper into Swift Evolution. While this newsletter keeps you informed about key developments, Proposal Monitor is ideal if you want to track every proposal, stay up-to-date with push notifications, or give timely feedback during review periods. Available on iOS, iPadOS, and visionOS, it’s a fantastic tool for following Swift’s evolution more closely. 🚀
No matter if you're stuck with a problem or just want feedback for your code or app idea. Book a session with me and I'll help you!