Update your code to use new language features and test your apps against changes.
SDK
- Xcode 10.2+Beta
Overview
Read these notes when you’re writing Swift apps in Xcode 10.2.
General
Swift 5 Runtime Support for Command Line Tools Package
Starting with Xcode 10.2 beta 3, Swift command line tools require the Swift libraries in macOS. They’re included by default starting with macOS Mojave 10.14.4 beta 3. In macOS Mojave 10.14.3 and earlier, there’s an optional package to provide these runtime support libraries for Swift command line tools that you can download from More Downloads for Apple Developers. If you install the beta version of this package, be sure to replace it with the release version when it’s available. This package is only needed for Swift command line tools, not for apps with graphical user interfaces.
App Thinning
New Features
Swift apps no longer include dynamically linked libraries for the Swift standard library and Swift SDK overlays in build variants for devices running iOS 12.2, watchOS 5.2, and tvOS 12.2. As a result, Swift apps can be smaller when deployed for testing using TestFlight, or when thinning an app archive for local development distribution.
To see the difference in file sizes between an app that’s thinned for iOS 12.2 and an app that’s thinned for iOS 12.1 or earlier, set your app’s deployment target to iOS 12.1 or earlier, then create an archive of your app with the scheme set to Generic iOS Device. After building the archive, select Distribute App from the Archives organizer, then select Development distribution. Be sure to select a specific device—such as iPhone XS—in the App Thinning pull-down menu. When the distribution process completes, open the App Thinning Size Report in the newly created folder. The variant for iOS 12.2 will be smaller than the variant for iOS 12.1 and earlier. The exact size difference depends on the number of system frameworks your app uses.
For information about app thinning, see What is app thinning? in Xcode Help. For information about app file sizes, see View builds and file sizes in App Store Connect Help.
Swift Language
New Features
String literals can now be expressed using enhanced delimiters. A string literal with one or more number signs (
#
) before the opening quote treats backslashes and double-quote characters as literal unless they’re followed by the same number of number signs. Use enhanced delimiters to avoid cluttering string literals that contain many double-quote or backslash characters with extra escapes (SE-0200) (47725014):
print(#"<a href="\#(url)" title="Apple Developer">"#)
// Equivalent to:
print("<a href=\"\(url)\" title=\"Apple Developer\">")
If you declare a type that has the same name as a type in the standard library, your type now shadows the type from the standard library. (46767892)
For example, if you declare a
Result
type in a module namedFoo
:
// Module `Foo`.
public enum Result<T> {
case value(T)
case error(Error)
}
Unqualified references to Result
in any of your code that imports the Foo
module will resolve to Foo
:
import Foo
func doSomething() -> Result<Int> { /* … */ }
To refer to the Result
type from the Swift standard library instead, qualify the access with the prefix “Swift.
”. For example:
import Foo
func useStandardLibraryResult() -> Swift.Result<Int, Error> { /* … */ }
The
@dynamic
attribute lets you call named types like you call functions using a simple syntactic sugar. The primary use case is dynamic language interoperability. (SE-0216)Callable For example:
@dynamicCallable struct ToyCallable {
func dynamicallyCall(withArguments: [Int]) {}
func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, Int>) {}
}
let x = ToyCallable()
x(1, 2, 3)
// Desugars to `x.dynamicallyCall(withArguments: [1, 2, 3])`
x(label: 1, 2)
// Desugars to `x.dynamicallyCall(withKeywordArguments: ["label": 1, "": 2])`
Key paths now support the identity keypath (
\.self
), aWritable
that refers to its entire input value (SE-0227):Key Path
let id = \Int.self
var x = 2
print(x[keyPath: id]) // Prints "2"
x[keyPath: id] = 3
print(x[keyPath: id]) // Prints "3"
Prior to Swift 5, you could write an enumeration case that took variadic arguments:
enum X {
case foo(bar: Int...)
}
func baz() -> X {
return .foo(bar: 0, 1, 2, 3)
}
This wasn’t intentionally supported and now generates an error. (46821582)
Instead, change the enumeration case to take an array and explicitly pass an array in:
enum X {
case foo(bar: [Int])
}
func baz() -> X {
return .foo(bar: [0, 1, 2, 3])
}
In Swift 5 mode,
try?
with an expression of anOptional
type flattens the resulting optional, instead of returning a nested optional. (SE-0230)If a type
T
conforms to one of the protocols in Initialization with Literals—such asExpressible
—and literal is a literal expression, thenBy Integer Literal T(
literal)
creates a literal of typeT
using the corresponding protocol, rather than calling an initializer ofT
with a value of the protocol’s default literal type.For example, expressions like
UInt64(0xffff
are now valid, where previously they would overflow the default integer literal type of_ffff _ffff _ffff) Int
. (SE-0213)String interpolation has improved performance, clarity, and efficiency. (SE-0228)
The older
_Expressible
protocol is removed; if you have code that makes use of this protocol, you need to update it for the new design. You can useBy String Interpolation #if
to conditionalize code between Swift 4.2 and Swift 5. For example:
#if compiler(<5)
extension MyType: _ExpressibleByStringInterpolation { /*...*/ }
#else
extension MyType: ExpressibleByStringInterpolation { /*...*/ }
#endif
Swift Standard Library
New Features
The standard library now includes the
Result
enumeration withResult
and.success(_:) Result
cases. Use.failure(_:) Result
to manually propagate and handle errors in situations wheredo-catch
statements and thetry
expression can’t be used, such as when you’re using asynchronous APIs that can fail.As part of this addition, the
Error
protocol now conforms to itself, which makes working with errors in a generic context easier. (SE-0235) (21200405)SIMD
types and basic operators are now defined in the standard library. The types provided by the simd framework, likefloat2
andfloat3
, are now type aliases of the new standard library types.SIMD types are generic over the scalar element type. For example, the old
float3
type is a type alias ofSIMD3<Float>
. Any type that conforms to theSIMDScalar
protocol can be used as a scalar type for SIMD vectors, but effective vectorization depends on choosing a good data layout and having efficient subscript operations for the associatedSIMDStorage
types.Most existing code using
simd
types will continue to work with the new generic SIMD types, but there are a few changes to note in particular:The new types add some new conformances; SIMD vectors are now
Hashable
,Equatable
, andCodable
. This may allow you to delete some existing extensions that provide these conformances in your own code.The set of operators that are overloaded to provide vector-scalar arithmetic is greatly expanded. This makes it easier to write some things, but in some cases introduces ambiguity to the typechecker and may make it necessary to break apart some expressions or annotate with explicit types.
Because the types are now generic rather than concrete, if you have defined your own protocols over the
simd
framework types, it may be necessary to refactor the conformances because a Swift generic type can’t have multiple conditional conformances to a protocol. This situation is relatively rare, but what you need to do in general is refactor code that looks like this:
protocol MyVectorProtocol { /* ... */ }
extension float2: MyVectorProtocol { /* ... */ }
extension double2: MyVectorProtocol { /* ... */ }
To use the following structure instead:
protocol MySIMDScalarProtocol: SIMDScalar { /* ... */ }
extension SIMD2 where Scalar: MySIMDScalarProtocol { /* ... */ }
// Or even:
protocol MySIMDScalarProtocol: SIMDScalar { /* ... */ }
extension SIMD where Scalar: MySIMDScalarProtocol { /* ... */ }
This change will frequently allow you to remove many redundant implementations, but it requires that you define any necessary implementation hooks that reference the concrete functions from the C headers on Darwin systems on the scalar type. (SE-0229) (17045503)
Set
andDictionary
now use a different hash seed for each newly created instance. As a consequence, the order of elements in equal sets and dictionaries is different much more often than in previous versions:
let a: Set<Int> = [1, 2, 3, 4, 5]
let b: Set<Int> = [1, 2, 3, 4, 5]
a == b // true
print(a) // [1, 4, 3, 2, 5]
print(b) // [4, 2, 5, 1, 3]
Existing code that incorrectly assumes that two unrelated but equal sets or dictionaries would contain elements in the same order produces incorrect results more often in Swift 5. Although element ordering isn’t stable across distinct Set
or Dictionary
instances, the order doesn’t vary between multiple iterations over the same instance. Beyond emphasizing that these collections don’t guarantee consistent element ordering, this change also fixes a number of cases where bulk operations—such as union(_:)
—exhibited quadratic performance. (44760778)
To help prevent inconsistent hashing for Cocoa objects, the
hash
property onValue NSObject
is no longer overridable. Overrides ofhash
were deprecated in Swift 4.2. To customize hashing inValue NSObject
subclasses, override thehash
property. The following example shows a sample implementation:
class Person: NSObject {
let name: String
init(name: String) {
self.name = name
super.init()
}
override func isEqual(_ other: Any?) -> Bool {
guard let other = other as? Person else { return false }
return other.name == self.name
}
override var hash: Int {
var hasher = Hasher()
hasher.combine(name)
return hasher.finalize()
}
}
Hashing and equality go hand in hand. If you override hash
, you also need to override is
, and vice versa. (42623458)
The
Dictionary
type is renamedLiteral Key
. (SE-0214) (23435865)Value Pairs Swift strings bridged into Objective-C code may now return a non-
nil
value fromCFString
when appropriate, and the pointer returned fromGet CString Ptr(_: _:) -UTF8String
is tied to the string’s lifetime rather than the innermost autorelease pool. Correct programs shouldn’t have any problems and may see significant speed-ups. However, it may cause previously untested code to run, which could expose latent bugs; for example, if there’s a check for a non-nil
value, the branch may never have been taken prior to Swift 5. (26236614)The
Sequence
protocol no longer has aSub
associated type. Methods onSequence Sequence
that previously returnedSub
now return concrete types. For example,Sequence suffix(_:)
now returns anArray
. (45761817)Extensions on
Sequence
that useSub
should be amended to either similarly use a concrete type, or be amended to be extensions onSequence Collection
instead, whereSub
remains available.Sequence For example:
extension Sequence {
func dropTwo() -> SubSequence {
return self.dropFirst(2)
}
}
Becomes:
extension Sequence {
func dropTwo() -> DropFirstSequence<Self> {
return self.dropFirst(2)
}
}
Or:
extension Collection {
func dropTwo() -> SubSequence {
return self.dropFirst(2)
}
}
The
String
structure’s native encoding switched from UTF-16 to UTF-8, which may improve the relative performance ofString
compared to.UTF8View String
. Consider re-evaluating any code specifically tuned to use.UTF16View String
for performance. (42339222).UTF16View
Known Issues
Setting the
utf8
property on a string has no effect. (47864538)Workaround: Create a new string instead:
// Has no effect:
myString.utf8 = bytes
// Workaround:
myString = String(decoding: bytes, as: UTF8.self)
Passing a null
Unsafe
Buffer Pointer <UInt8>
to theString
structure’sinit(decoding:
initializer may cause a crash. (47864610)as:)
Swift Package Manager
New Features
Targets can now declare some commonly used, target-specific build settings when using the Swift 5
Package
.swift tools-version
. The new settings can also be conditionalized based on platform and build configuration. The included build settings support Swift- and C-language defines, C language header search paths, linked libraries, and linked frameworks. (SE-0238) (23270646)Packages can now customize the minimum deployment target setting for Apple platforms when using the Swift 5
Package
.swift tools-version
. Building a package emits an error if any of the package dependencies of the package specify a minimum deployment target greater than the package’s own minimum deployment target. (SE-0236) (28253354)A new dependency mirroring feature allows top-level packages to override dependency URLs. (SE-0219) (42511642)
Use the following command to set a mirror:
$ swift package config set-mirror \
--package-url <original URL> --mirror-url <mirror URL>
The
swift test
command can generate code coverage data in a standard format suitable for consumption by other code coverage tools using the flag--enable-code-coverage
. The generated code coverage data is available inside <build-dir>/
<configuration>/codecov
. (44567442)Swift 5 no longer supports the Swift 3
Package
.swift tools-version
. Packages still on the Swift 3Package
.swift tools-version
should update to a newertools-version
. (41974124)Package manager operations for larger packages are now significantly faster. (35596212)
The Swift Package Manager has a new
--disable-automatic-resolution
flag that forces the package resolution to fail when thePackage
entries are no longer compatible with the dependency versions specified in the.resolved Package
manifest file. This feature can be useful for a continuous integration system to check if a package’s.swift Package
is out of date. (45822895).resolved The
swift run
command has a new--repl
option that launches the Swift REPL with support for importing library targets of a package. This allows you to easily experiment with API from a package target without needing to build an executable that calls that API. (44889181)For more information about using the Swift Package Manager, visit Using the Package Manager on swift.org.
Swift Compiler
New Features
To reduce the size taken up by Swift metadata, convenience initializers defined in Swift now only allocate an object ahead of time if they’re calling a designated initializer defined in Objective-C. In most cases, this has no effect on your app, but if your convenience initializer is called from Objective-C and doesn’t in turn delegate via
self
to an initializer exposed to Objective-C, the initial allocation from.init alloc
is released without any initializer being called. This can be problematic for users of the initializer that don’t expect any sort of object replacement to happen. One instance of this is withinit(coder:)
: the implementation ofNSKeyed
may behave incorrectly if it calls into Swift implementations ofUnarchiver init(coder:)
and the archived object graph contains cycles.To avoid this, ensure that convenience initializers that don’t support object replacement always delegate to initializers that are also exposed to Objective-C, either because they’re defined in Objective-C, or because they’re marked with
@objc
, or because they override initializers exposed to Objective-C, or because they satisfy requirements of an@objc
protocol. (46823518)C types with an alignment greater than 16 bytes are no longer available in Swift. The Swift compiler never handled these types correctly. (31411216)
In Swift 5 mode, the type of
self
in a convenience initializer of a nonfinal class is now the dynamicSelf
type, and not the concrete class type. (47323459)Exclusive memory access is now enforced at runtime by default in optimized (
-O
and-Osize
) builds. Programs that violate exclusivity will trap at runtime with an “overlapping access” diagnostic message. You can disable this using a command line flag:-enforce-exclusivity=unchecked
, but doing so may result in undefined behavior. Runtime violations of exclusivity typically result from simultaneous access of class properties, global variables—including variables in top-level code—or variables captured by escaping closures. (SR-7139) (37830912)Swift 3 mode has been removed. Supported values for the
-swift-version
flag are4
,4
, and.2 5
. (43101816)In Swift 5 mode, switches over enumerations that are declared in Objective-C or that come from system frameworks are required to handle unknown cases—cases that might be added in the future, or that may be defined privately in an Objective-C implementation file. Formally, Objective-C allows storing any value in an enumeration as long as it fits in the underlying type. These unknown cases can be handled by using the new
@unknown default
case, which still provides warnings if any known cases are omitted from the switch. They can also be handled using a normaldefault
case.If you’ve defined your own enumeration in Objective-C and you don’t need clients to handle unknown cases, you can use the
NS
macro instead of_CLOSED _ENUM NS
. The Swift compiler recognizes this and doesn’t require switches to have a default case._ENUM In Swift 4 and 4.2 modes, you can still use
@unknown default
. If you omit it and an unknown value is passed into the switch, the program traps at runtime, which is the same behavior as Swift 4.2 in Xcode 10.1. (SE-0192) (39367045)Default arguments are now printed in SourceKit-generated interfaces for Swift modules, instead of just using a placeholder default. (18675831)
unowned
andunowned(unsafe)
variables now supportOptional
types. (47326769)
Known Issues
Linking a Swift program directly from the command line with the
swiftc
compiler results in output that crashes when run on macOS Mojave 10.14.4 beta 3 with an error: “This copy of libswiftCore.dylib requires an OS version prior to 10.14.4.” (43616773)The expression
self
is erroneously allowed in designated initializers in subclasses of.init() NSView
andUIView
, even thoughinit()
is a convenience initializer onNSView
andUIView
. Usingself
can result in stored properties being initialized more than once, which leads to memory leaks and other possible issues in your app. (SR-9836) (47734208).init() Workaround: Use
super
instead..init(frame:) To reduce the size taken up by Swift metadata, convenience initializers defined in Swift now only allocate an object ahead of time if they’re calling a designated initializer defined in Objective-C. In most cases, this has no effect on your program, but if your convenience initializer is called from Objective-C, the initial allocation from
+alloc
is released without any initializer being called. This can be problematic for users of the initializer that don’t expect any sort of object replacement to happen. One instance of this is withinit(coder:)
: the implementation ofNSKeyed
may behave incorrectly if it calls into Swift implementations ofUnarchiver init(coder:)
and the archived object graph contains cycles.In a future release, the compiler will guarantee that a convenience initializer never discards the object it was invoked on as long as the initializer it delegates to via
self
is also exposed to Objective-C, either because it’s defined in Objective-C, or because it’s marked with.init @objc
, or because it overrides an initializer exposed to Objective-C, or because it satisfies a requirement of an@objc
protocol. (46823518)Swift command line projects won’t run on macOS 10.14.3 and earlier unless you install the Swift 5 Runtime Support for Command Line Tools package. Without that package, Swift command line projects crash on launch with “dyld: Library not loaded” errors. (46824656)
Resolved Issues
Compile time regressions in beta releases of Xcode 10.2, as compared to Xcode 10.1, are now resolved in most cases. Some projects may continue to experience small regressions; file bug reports for cases you encounter. (47304789)
The Swift compiler completes the “Merge swiftmodule” build step even if members of the
UIAccessibility
structure or other types that containNS
nested types are referenced. (47152185)_ERROR _ENUM Single-element labeled tuple expressions, like
(label: 123)
, were allowed in some contexts but often resulted in surprising, inconsistent behavior that varied across compiler releases. They’re now completely disallowed.Single-element labeled types, like
var x: (label: Int)
, were prohibited starting in Swift 3. (SR-8109) (41474370)If a key path literal refers to a property that’s defined in Objective-C or that’s defined with the
@objc
anddynamic
modifiers in Swift, it now compiles successfully and generates the correct hash value or equality comparison with other key paths at runtime. (47184763)Extension binding now supports extensions of nested types which themselves are defined inside extensions. Previously this could fail with some declaration orders, producing spurious “undeclared type” errors. (SR-631) (20337822)
In Swift 5 mode, a class method that returns
Self
can no longer be overridden with a method that returns a concrete class type that isn’tfinal
. Such code isn’t type safe and needs to be updated. (SR-695) (47322892)For example:
class Base {
class func factory() -> Self { /*...*/ }
}
class Derived: Base {
class override func factory() -> Derived { /*...*/ }
}
In Swift 5 mode, attempting to declare a static property with the same name as a nested type is now always correctly rejected. Previously, it was possible to perform such a redeclaration in an extension of a generic type. (SR-7251) (47325738)
For example:
struct Foo<T> {}
extension Foo {
struct i {}
// Error: Invalid redeclaration of 'i'.
// (Prior to Swift 5, this didn’t produce an error.)
static var i: Int { return 0 }
}
Designated initializers with variadic parameters are now correctly inherited in subclasses. (16331406)
In Swift 5 mode,
@autoclosure
parameters can no longer be forwarded to@autoclosure
arguments in another function call. Instead, you must explicitly call the function value with parentheses:()
; the call itself is wrapped inside an implicit closure, guaranteeing the same behavior as in Swift 4 mode. (SR-5719) (37321597)For example:
func foo(_ fn: @autoclosure () -> Int) {}
func bar(_ fn: @autoclosure () -> Int) {
foo(fn) // Incorrect, `fn` can’t be forwarded and has to be called.
foo(fn()) // OK
}
Complex recursive type definitions involving classes and generics that would previously cause deadlocks at runtime are now fully supported. (38890298)
In Swift 5 mode, when casting an optional value to a generic placeholder type, the compiler will be more conservative with the unwrapping of the value. The result of such a cast now more closely matches the result you would get in a nongeneric context. (SR-4248) (47326318)
For example:
func forceCast<U>(_ value: Any?, to type: U.Type) -> U {
return value as! U
}
let value: Any? = 42
print(forceCast(value, to: Any.self))
// Prints "Optional(42)"
// (Prior to Swift 5, this would print "42".)
print(value as! Any)
// Prints "Optional(42)"
Protocols can now constrain their conforming types to those that subclass a given class. Two equivalent forms are supported:
protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ }
Swift 4.2 accepted the second form, but it wasn’t fully implemented and could sometimes crash at compile time or runtime. (SR-5581) (38077232)
In Swift 5 mode, when setting a property from within its own
did
orSet will
observer, the observer will now only avoid being recursively called if the property is set onSet self
(either implicitly or explicitly). (SR-419) (32334826)For example:
class Node {
var children = [Node]()
var depth: Int = 0 {
didSet {
if depth < 0 {
// Won’t recursively call didSet, because this is setting depth on self.
depth = 0
}
// Will call didSet for each of the children,
// as this isn’t setting the property on self.
// (Prior to Swift 5, this didn’t trigger property
// observers to be called again.)
for child in children {
child.depth = depth + 1
}
}
}
}
#source
is now honored when diagnostics are emitted in Xcode. That is, if your source usesLocation #source
to map lines in a generated file back to the original source, diagnostics now show up in the original source file rather than in the generated file. (43647151)Location Using a generic type alias as the parameter or return type of an
@objc
method no longer results in the generation of an invalid Objective-C header. (SR-8697) (43347303)