New Features and Improvements in Swift 4
This article comprehensively outlines Swift 4’s new syntax, language enhancements, standard‑library updates, performance improvements, and Xcode 9 build‑system changes, providing code examples and explanations to help iOS developers adopt the latest features in modern app development.
Author: Liu Duo (Senior iOS Engineer at Hujiang)
Original article, please credit the author and source when reposting
WWDC 2017 introduced many surprises, and Swift 4 arrived together with the Xcode 9 beta. Because Swift 4 is open‑source, anyone following the swift‑evolution project can already see its new features. This article lists and analyses Swift 4’s new syntax, string handling, standard library changes, and build‑process improvements.
1. Syntax Improvements
Extension can access private properties
Reference the following code:
struct Date: Equatable, Comparable {
private let secondsSinceReferenceDate: Double
static func ==(lhs: Date, rhs: Date) -> Bool {
return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
}
static func <(lhs: Date, rhs: Date) -> Bool {
return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
}
}The code defines a Date struct and implements Equatable and Comparable . In Swift 3 the compiler reports an error because an extension cannot access a private property; you had to change it to fileprivate . Swift 4 expands the scope of private to extensions, eliminating the need for fileprivate .
Combined type and protocol syntax
In Swift 4 you can combine a type and a protocol with & :
protocol Shakeable {
func shake()
}
extension UIButton: Shakeable { /* ... */ }
extension UISlider: Shakeable { /* ... */ }
func shakeEm(controls: [UIControl & Shakeable]) {
for control in controls where control.state.isEnabled {
control.shake()
}
}This resolves the earlier need for awkward casts or separate generic constraints.
Associated type with where clause
Swift 4 allows a where clause after an associatedtype declaration, e.g. in Sequence :
protocol Sequence {
associatedtype Element where Self.Element == Self.Iterator.Element
associatedtype Iterator: IteratorProtocol where Iterator.Element == Element
func makeIterator() -> Iterator
}New Key‑Path syntax
Key‑paths now start with a backslash:
\Kid.nickname
let name = ben[keyPath: \Kid.nickname]
ben[keyPath: \Kid.nickname] = "BigBen"They are type‑safe, work on structs, and no longer require @objcMembers or dynamic .
Subscript generic support
struct GenericDictionary<Key: Hashable, Value> {
private var data: [Key: Value]
init(data: [Key: Value]) { self.data = data }
subscript<T>(key: Key) -> T? { return data[key] as? T }
}
let dictionary = GenericDictionary(data: ["Name": "Xiaoming"])
let name: String? = dictionary["Name"]2. String Improvements
Unicode count correctness
Swift 4 counts a composed emoji sequence as a single character, fixing the Swift 3 behaviour.
Faster character processing
Performance for English, French, German, and Spanish strings improves by ~3.5×; for Simplified Chinese and Japanese by ~2.5×.
Removal of characters property
String APIs now operate directly on String without the intermediate characters view.
One‑sided slicing
let values = "abcdefg"
let start = values.index(values.startIndex, offsetBy: 3)
let sub = values[start...]String as a Collection
Strings now support collection methods such as map , filter , reduce , and can be reversed directly.
Multi‑line string literals
let joke = """
Q: Why does \(name) have \(n) \(character)'s in their name?
A: I don't know…
"""3. Standard Library Updates
Codable
Swift 4 introduces Codable to replace manual NSCoding implementations.
struct Language: Codable {
var name: String
var version: Int
}
let swift = Language(name: "Swift", version: 4)
let encoded = try? JSONEncoder().encode(swift)
let decoded = try? JSONDecoder().decode(Language.self, from: encoded!)Dictionary and Set enhancements
Initialisation from a Sequence
Allow duplicate keys during construction
mapValues and default‑value subscripting
Grouping and inversion utilities
MutableCollection.swapAt(_:_:)
var arr = [1, 2, 3, 4]
arr.swapAt(1, 2) // [1, 3, 2, 4]4. Build Process Improvements
New Build System
Xcode 9 introduces a new build system selectable via File → Project Settings… .
Pre‑compiled Bridging Headers
Bridging headers are now compiled once and reused, cutting mixed Swift/Objective‑C build times by ~40%.
Indexing during compilation
Indexing now runs in parallel with compilation, reducing overall wait time.
COW Existential Containers
Copy‑On‑Write containers reduce heap allocations for large existential values.
Reduced implicit @objc inference
Only required places now get implicit @objc , shrinking binary size (Apple Music app down 5.7%).
5. Exclusive Access to Memory
Swift 4 adds compile‑time checks that prevent mutating a collection while simultaneously iterating it, avoiding runtime crashes.
6. Compatibility
Xcode 9 ships with both Swift 3.2 (fully compatible with Swift 3.1) and Swift 4, allowing mixed‑module compilation and a smoother migration path.
7. References
WWDC 2017 Session 402 “What’s New in Swift”
WWDC 2017 Session 212 “What’s New in Foundation”
WWDC 2017 Session 102 “Platforms State of the Union”
Swift Language Programming (Swift 4.0)
swift‑evolution
what’s‑new‑in‑swift‑4
Ray Wenderlich article
Hacking with Swift 4
Hujiang Technology
We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.