Monday, July 17, 2017

What’s New in Swift

This article is just a short overview of this WWDC session.


Here are the few things that were discussed as part of the session:


1.) Private variables are now accessible to all the extensions of the class in the same file.


2.) Composing a class with any number of protocols.

Example : 
protocol Shakeable {
    func shake()
}
extension UIButtonShakeable {}
extension UISliderShakeable {}
func shakeControls(controls: [UIControl & Shakeable]) {
    for control in controls where control.state.isEnabled {
        control.shake()
    }
}

3.) Swift Versions:

Swift 4 is source-compatible with Swift3.
Swift3.2 introduced that contains most of the Swift4 syntax changes.
So, there will be 2 Swift versions in Xcode9: Swift3.2  & Swift4.

The end result is: If you open a Swift 3 project in Xcode9 and build the project with Swift3.2, it should work as it is, i.e., without any code changes.
This is mainly to give the developers time to adopt to the new Swift changes, so that the project dependencies can migrate asynchronously.

4.) New faster Build system:

Includes these:
(i) The pre-compiled header is the default option for compatibility between Obj-C & Swift classes.
The Bridging headers are build each time when a build is run, whereas the Xcode9’s default ‘Pre-Compiled header’ is build only once, which improves the build time for projects that contains huge amount of Legacy Objective-C classes.

(ii) Code Coverage: Xcode8 runs a separate build, where Xcode 9 will use the same last build when you run a test with Code Coverage, which eventually reduces the test execution time.

(iii) Indexing is not a separate background process now, it is done along with the build process that has a small overhead to the build, of course.

(iv) No unused code is build, the compiler just omits it. (It doesn’t mean that we should have unused code in our projects ;) )


5.) Strings:
(i) String collections can be directly manipulated without using the internal ‘characters’ collection.

Example:
let values = "one, two, three…"

//To get index after the ‘,’ char from the ‘values’ string
Swift 3:
while let comma = values[i..<values.endIndex].index(of: ",") {
    let index = values.index(after: comma)
}

Swift4:
while let comma = values[i..<values.endIndex].index(of: ",") {
    let index1 = values.characters.index(after: comma)
}

(ii) String ‘characters’ collection iteration can be iterated without using ‘values.endIndex’ in the below example.

Swift 3:
var i = values.startIndex
while let comma = values[i..<values.endIndex].index(of: ",") {
}

Swift 4:
var i = values.startIndex
while let comma = values[i...].index(of: ",") {
}

(iii) Substring cannot be used as it is from Swift 4. It needs to be copied before using it further, this is to overcome an issue of memory leak with Substring before Swift4.

Example:
let big = downloadHugeString()
let small = extractTinyString(from: big)

Swift 3:

myLabel.text = small // This leads to the memory leak, since the 'big' text is being holded by the internal String classes that does the process of extracting the substring from the given 'big' string.
Swift 4:

myLabel.text = String(small)//Hence, this is the recommended/only way to use the substring going forward.
This mainly affects huge string operation. Doesn’t majorly have any great effect on the small string manipulations.



(iv) Multi line strings literals are easier to write now.

Swift 3:

let longString = "Q1: Why does \(name) have \(n\(characters)'s in their name?\nA: I don't know.Q2: H r u?\nA: I am \(name)"
Swift 4:
let longString = """
                Q1: Why does \(name) have \(n) \(characters)'s in their name?
                A: I don't know.
                Q2: H r u?
                A: I am \(name)
                """