Original: What's New in Swift 3?
Ben Morrow
Translator: Kmyhy
Swift 3 will be withdrawn in the second half of the year, and it has brought many changes for swift programmers.
If you don't pay close attention to the Swift Evolution project, you may not know what changes it is and how it will affect your code as you move the code to Swift 3 o'clock. Then you may need to read this article.
In this article, I'll focus on the major changes in Swift 3, which have a profound impact on your code. Let's get started!
Begin
Currently, Swift 3 is only available in the Xcode 8 beta release. In the coming months, Swift 3 is still changing, and there are some changes. At the end of 2016, when Xcode GM was released, the new features of Swift 3 would be fixed. So you should take your time and wait until then to submit an app written in Swift 3 to the app Store.
To make it easier for developers to migrate code to Swift 3, Apple added a swift version to Xcode 8, the Swift 2.3, which made a minor upgrade to Swift. If you are a developer, Swift 2.3 and 2.2 are not actually different, but 2.3 can support the new SDKs and Xcode features mentioned in WWDC. When you launch the beta version of Xcode 8, you can submit your app with Swift 2.3来 instead of migrating the code to Swift 3.
I recommend that you test the new features discussed in this article in Playground, and you can test migration Assistant with one of your projects so that you know about these changes. Since you can't submit apps to the app Store until the next version of Xcode 8 beta and SIWFT 3 is officially released, you can temporarily leave the code migrated to Swift 3 until these issues are resolved.
Upgrade to Swift 3
In the upgrade to Swift 3 o'clock, you will find that basically every file needs to be changed! This is because all the Cocoa API names have been changed. In short, the API is still the original API, but this API is called in Objective-c, and in Swift it is another term. The Swift 3 syntax is written more closely to the natural language.
In Xcode 8, Apple offers the migration Assistant, which can do most of the migration work. But obviously, there's still a part of the work you need to do manually.
You can immediately upgrade the code to 2.3 or 3.0. If you need to turn the code back in, you can use Xcode's Edit > Convert > to current Swift Syntax ... Menu. The compiler will be as smart as Migrateion Assistant. If you accidentally use the old API when you invoke the method, the compiler displays a fixt-it option that lets you use the correct new API. Fortunately, Swift 3 will not stop changing the source code until it is finally released. Therefore, you can save your Swift code to a different version. However, the Swift core team cannot guarantee that this will not change, and if at some point it is not guaranteed to be compatible with the source, they will provide a longer transition period. This means that the source code is stable so that more conservative companies can be encouraged to use it.
This also shows that the goal of binary stability has not yet been achieved. The implications of this will be discussed at the end of this article.
The implemented Swift Evolution offer
Since Swift Open source, community members have submitted more than 100 recommendations for improvement. Most (more than 70) of these proposals have been accepted after the discussion has been revised. Still others have been rejected after a heated debate. But in the end, all the proposals go through the core team's final decision.
Collaboration between the core team and the wider community is fruitful. In fact, Swift has gained more than 30,000 stars on Github. New proposals are submitted every week, JoJo. Even Apple's engineers will submit their proposals on Github.
In the next section, you'll see some annotations like [SE-0001]. This is an accepted proposal number and will be implemented in the final version of Swift 3.0. Each proposal is marked so that you can see the specifics of each change.
Changes to the API
The biggest change in Swift 3 is that the standard library uses a unified naming method in each library. These rules are included in API Design guidleines, which is used by the core team when building Swift 3, which is highly readable and easy to use for beginners. The core team follows the principle that a good API design should always look at the problem from the caller's point of view. They strive to make the API easy to use. No more, let's start by talking about the changes that are so important to you.
The label of the first parameter
Let's start with the examples you'll use in Swift every day.
The first argument in a function or method must now have a label unless you explicitly declare it not. Previously, when we called a function or method, we could ignore the label[se-0046 of the first argument]:
// The first sentence is the Swift 2 syntax, and the second sentence is the Swift 3 syntax.
"RW".writeToFile("filename", atomically: true, encoding: NSUTF8StringEncoding)
"RW".write(toFile: "filename", atomically: true, encoding: NSUTF8StringEncoding)
SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10)
SKAction.rotate(byAngle: CGFloat(M_PI_2), duration: 10)
UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
UIFont.preferredFont(forTextStyle: UIFontTextStyleSubheadline)
Override func numberOfSectionsInTableView(tableView: UITableView) -> Int
Override func numberOfSections(in tableView: UITableView) -> Int
Func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
Func viewForZooming(in scrollView: UIScrollView) -> UIView?
NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)
NSTimer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)
Note that some methods use the preposition "of", "to", "with" and "in" as external parameter names. This is to increase the readability of the code.
If this method does not use a preposition and does not use a label, you should explicitly precede the first parameter name with an underscore when the method is defined:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { ... }
override func didMoveToView(_ view: SKView) { ... }
In many programming languages, many methods can share a method name, but the name of the parameter differs. Swift is no exception, and now you can overload methods that APIs will be able to convert directly into appropriate calls. Here is an example that shows two overloaded forms of the Index () method:
let names = ["Anna", "Barbara"]
if let annaIndex = names.index(of: "Anna") {
print("Barbara‘s position: \(names.index(after: annaIndex))")
}
The method name is the same, but the parameter name is different, which makes it easier to remember.
Omit unnecessary words
In the past, in the Apple standard Library, the method name contains a word that indicates the return value of the method. Because Swift compiles support type inference, this practice is not necessary. The core team filters out all the "noise" as much as possible, so the duplicate words are removed, leaving only the most important part of the method name.
The API has become smarter in translating the Objective-c library into a cost-effective Swift language [SE-0005]:
// The first sentence is the Swift 2 syntax, and the second sentence is the Swift 3 syntax.
Let blue = UIColor.blueColor()
Let blue = UIColor.blue()
Let min = numbers.minElement()
Let min = numbers.min()
attributedString.appendAttributedString(anotherString)
attributedString.append(anotherString)
Names.insert("Jane", atIndex: 0)
Names.insert("Jane", at: 0)
UIDevice.currentDevice()
UIDevice.current()
The new GCD and Core Graphics
The legacy of the "Elder" API,GCG and Core Graphics need to be re-"dressed up".
The Grand Central Dispatch is often used for long-time calculations or for communicating with servers. You can avoid blocking the user interface by putting tasks on different threads. The Libdispatch library is written in C and provides a C-style API. This API is now redesigned as [SE-0088] in Swift:
// Swift 2 syntax
Let queue = dispatch_queue_create("com.test.myqueue", nil)
Dispatch_async(queue) {
Print("Hello World")
}
// Swift 3 syntax
Let queue = DispatchQueue(label: "com.test.myqueue")
Queue.async {
Print("Hello World")
}
The same is the case with the Core Graphics. The Core Graphics are written in C and have been called only in "ugly" functions. This is its new usage [SE-0044]:
// Swift 2 syntax
Let ctx = UIGraphicsGetCurrentContext()
Let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
CGContextSetFillColorWithColor(ctx, UIColor.blueColor().CGColor)
CGContextSetStrokeColorWithColor(ctx, UIColor.whiteColor().CGColor)
CGContextSetLineWidth(ctx, 10)
CGContextAddRect(ctx, rectangle)
CGContextDrawPath(ctx, .FillStroke)
UIGraphicsEndImageContext()
// Swift 3 syntax
If let ctx = UIGraphicsGetCurrentContext() {
Let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
ctx.setFillColor(UIColor.blue().cgColor)
ctx.setStrokeColor(UIColor.white().cgColor)
ctx.setLineWidth(10)
ctx.addRect(rectangle)
ctx.drawPath(using: .fillStroke)
UIGraphicsEndImageContext()
}
Case value in Enumeration
Another difference from the previous Swift code is that the case value defined in the enumeration now uses the small hump nomenclature. This is for consistency with the property name or variable name [SE-0006]:
// The first sentence is the Swift 2 syntax, and the second sentence is the Swift 3 syntax.
UIInterfaceOrientationMask.Landscape
UIInterfaceOrientationMask.landscape
NSTextAlignment.Right
NSTextAlignment.right
SKBlendMode.Multiply
SKBlendMode.multiply
The Big hump nomenclature is now used only on type names and protocol names. When you get used to all this, the Swift team is not in vain for the pursuit of consistency.
Method of returning a value or modifying a value
The rules for using verbs and nouns in the method names in the standard library are also more uniform. You should follow the results of this method or take some action to name the method. The first principle is that if the method name contains an "ed" or "ing" suffix, it is a noun. Method with the name of a noun has a return value. If you do not include these suffixes, it is likely that this is a verb. A verb-named method takes some action on a block of referenced memory. The so-called "Modify a value". Here are a few ways to match the noun/verb naming rules [SE-0006]:
customArray.enumerate()
customArray.enumerated()
customArray.reverse()
customArray.reversed()
customArray.sort() // changed from .sortInPlace()
customArray.sorted()
Here are some snippets of code that use these methods:
Var ages = [21, 10, 2] // variable, not a constant, so you can modify it
Ages.sort() // modify the value, now the value becomes [2, 10, 21]
For (index, age) in ages.enumerated() { // "-ed" is a noun indicating that an ages copy will be returned
Print("\(index). \(age)") // Print: 1. 2 \n 2. 10 \n 3. 21
}
###function type
When a function is declared and called, it needs to be enclosed in parentheses:
```swift
Func f(a: Int) { ... }
f(5)
<div class="se-preview-section-delimiter"></div>
However, when you use a function type as a parameter, you might write code like this:
Func g(a: Int -> Int) -> Int -> Int { ... } // Swift 2 syntax
<div class="se-preview-section-delimiter"></div>
You'll find the code hard to read. Where does the parameter end, and where does the return value start? In Swift 3, the correct way to define this is [SE-0066]:
func g(a: (Int) -> Int) -> (Int) -> Int { ... } // new way, Swift 3
<div class="se-preview-section-delimiter"></div>
The parameter list is now wrapped in parentheses and then the return type. Things are easy, and function types are easier to identify. By the following comparison, you will be more clear:
// Swift 2 syntax
Int -> Float
String -> Int
T -> U
Int -> Float -> String
// Swift 3 syntax
(Int) -> Float
(String) -> Int
(T) -> U
(Int) -> (Float) -> String
<div class="se-preview-section-delimiter"></div>
Enhancements to the API
In addition to the biggest change to the existing API "old bottle new"-There are a lot of swift communities working on this, as well as some functional additions to the Swift API.
Accessing the owning type
When you define a static property or method, you call them directly from the class or type:
CustomStruct.staticMethod()<divclass="se-preview-section-delimiter"></div>
If you are currently writing code inside a type, you will still use the type name to invoke the static method. To make the presentation clearer, you can now refer to the type that the current instance belongs to by self. The self in uppercase is a reference to the type of the current instance, while S is lowercase to reference the current instance itself.
This is a concrete example [SE-0068]:
Struct CustomStruct {
Static func staticMethod() { ... }
Func instanceMethod() {
Self.staticMethod() // inside the type
}
}
Let customStruct = CustomStruct()
customStruct.Self.staticMethod() // Apply the type on an instance
<div class="se-preview-section-delimiter"></div>
In-line sequences
Sequence (first:next:) and sequence (state:next:) is a global function that returns an infinite sequence. You pass them an initial value or a mutable state that will later invoke the code in the closure [SE-0094]:
for view in sequence(first: someView, next: { $0.superview }) {
// someView, someView.superview, someView.superview.superview, ...
}
<div class="se-preview-section-delimiter"></div>
You can also use the prefix operator to add a limit to a sequence [SE-0045]:
for view in sequence(first: someView, next: { $0.superview }) {
// someView, someView.superview, someView.superview.superview, ...
}
<div class="se-preview-section-delimiter"></div>
Miscellaneous
- #keyPath () equivalent to #selector () to help you reduce input errors
- You can invoke pi on certain types, such as: Float.pi, Cgfloat.pi. Most of the time the compiler can infer the type: let circumference = 2 *. pi * radius [SE-0067]
- The NS prefix is removed from the old Foundation type and can now be replaced with Calendar, date, Nscalendar, nsdate
Improvement of tools
Swift is a language, and most of the time you can't leave the development environment in which it is written-for Apple developers, that is xcode! Changes in tools affect the way you write your code every day.
Swift 3 Fixes bugs in the compiler and IDE, and improves the accuracy of reporting errors and information. As you would expect, the release of each release will make Swift and the compiler run faster:
- Improved Hash algorithm for strings, resulting in a 3 times-fold increase in performance after a string is stored in a dictionary
- Move objects from the heap to the stack, resulting in a 24 times-fold increase in performance (in some cases)
- The compiler can cache multiple files at once (in case the entire module is optimized)
- The size of the code is optimized, resulting in a smaller compilation size for Swift code. In the case of Apple's Demobots, the compilation size is reduced by 77% of the original size.
Xcode will also be more intelligent in understanding Swift code:
-
In the past, when you right-clicked on an API method such as sort () and jumped to the definition, you would see a header file that was not easily understood. Now, in Xcode 8, you'll see that the sort () method is actually an extension of the Array class.
-
Swift snapshots, as the Swift Evolution released tonight, said. Before fully merging to Xcode, snapshots provides an opportunity to use the new syntax. Xcode 8 is capable of loading and running Swift snapshots in Playgournd.
Swift Package Manager
Open source Swift actually contains the swift language itself, the core library, and the package manager. Together, these three constitute the Swift we have seen. The Package Manager defines a simple directory structure that includes the Swift code that you share and import into your project.
Similar to the package managers you have used Cocoapods or Carthage, Swift Package Manager downloads dependencies and compiles them, link them to accomplishment or executable files. There are already 1000 libraries that support the Swift Package Manager, and more libraries will support it in the coming months.
Features in the plan
As mentioned earlier, Swift 3 avoids incompatible changes as much as possible so that your code can be compatible from one version to the next. If this is true, then there should be some more ambitious goals in this release, namely, generics enhancement (generic additions) and ABI (program binary interface) are stable.
Generic enhancements include recursive protocol constraints and the ability to conform a constrained extension to a new protocol (for example, an array for storing equatable objects should also comply with the Equatable protocol). Before these features have been implemented, Swift cannot be considered an ABI stable.
ABI stabilization requires applications and libraries to be able to interact with each other regardless of which version of the compiler is compiled. This is an important step forward for third-party libraries, because this allows the framework to be encapsulated without the need to provide the source code, and now the new version of Swift does not only need these third-party libraries to modify the codes, but also to recompile.
In addition, if the ABI is stable, you can remove the Swift standard library contained in the binaries, because IOS and MacOS apps are now created with Xcode. Current binaries contain about 2 MB of file size in order to ensure compatibility with future operating systems.
In short, you can only keep the source code version compatible now, and binary version compatibility is still not possible at the moment.
End
Swift is still evolving because the community's goals are best practices. Although it is still young, it also faces tremendous opportunities and a bright future. Swift is now able to run on Linux, and in the next few years you will see it running on more servers and devices. Designing a language from scratch will inevitably undermine ABI stability, which becomes much smaller once it stabilizes. This (open source) is the only chance to make this language better, otherwise we will regret it.
Swift is expanding its reach. Apple is taking it personally. Apple's team is using Swift in the Music app, Console, Sierra Pip, Xcode Document Viewer, and the new IPad version of the Swift Playground app.
Here, Apple seems to have a way for non-programmers to learn swift intentions, such as the ability to use Swift on IPAD and some educational measures to demonstrate this.
In addition, Swift is continually improving: naming becomes more canonical, code reads clearer, and you can use tools to migrate code. If you want to learn more, see WWDC's conference video.
To be sure, the official release of Swift 3 at the end of 2016 will certainly be expected. We will continue to follow up on all changes, and please stay tuned for our tutorials, new book previews and videos, and we'll start using these exciting improvements.
What is the most exciting feature in Swift 3? Which one would you most like us to introduce? Please let us know in the comments below.
What's new in Swift 3