Seven Swift 2 enhancements every iOS developer will love

Apple makes good on Swift’s emphasis on performance, approachability, and ease in latest update

1 2 Page 2
Page 2 of 2

The introduction of protocol extensions also brings new APIs, and with this, most free-standing global functions have been removed. As a result, the standard dot syntax variableName.methodName() is now readily available for you to use, thereby enhancing API discoverability and coder productivity.

With protocol extensions in Swift 2, if a feature or method doesn’t exist, you can write your own. For example, you can extend the Array structure that Apple provides with new functions or methods. In Objective-C, the NSMutableArray has a method to remove multiple elements as a single line of code, named removeObjectsInArray:. In Swift (2.1) there is no method to remove multiple elements from the Swift Array structure using a single method call. Using a protocol extension, you can add this method to the Array structure.

// Extend the Array class when Elements are comparable
extensionArraywhere Element: Equatable { 
   // Remove a single Element if it is found in the Array
   mutating func removeObject(object: Element) {
       if let index = self.indexOf(object) {
           self.removeAtIndex(index)
       }
   } 
   // Remove multiple Elements using the previous method and a loop
   mutating func removeObjectsInArray(array: [Element]) {
       for object in array {
           self.removeObject(object)
       }
   }
}
var students = ["John", "Sue", "Michael", "Chris", "David", "Benjamin"]
var studentsToRemove = ["Michael", "David", "Benjamin"]
print("Students: ", students)
// Remove an array of student names
students.removeObjectsInArray(studentsToRemove)
print("Students: ", students)
students.removeObject("John")
print("Students: ", students)
download
Example playground files for Swift 2 Paul Solt/InfoWorld

This kind of protocol extension will allow you to reuse a few lines of code in your app without having to copy/paste the same logic into every code file you need to maintain.

OptionSetType

Apple has worked to make Swift more approachable, and one such change is Swift 2’s movement away from traditional bit mask options. Swift 2’s new OptionSetType uses set logic instead of bitwise operations (which is not the best-understood topic for beginners, nor should it be required).

Traditional Objective-C and C APIs have used bitwise operations to logically combine multiple options in order to pass as a single value -- an optimization at the bit level that requires an understanding of how bit masks and bitwise operations work. With OptionSetType it’s no longer necessary to fully understand bit masks to create and sell apps on the App Store.

This is a win for developers because it frees them of a legacy programming model that requires more hard-to-read boilerplate code.

Apple has also revamped all of the Objective-C APIs that required NS_OPTIONS values to use the new OptionSetType. This causes breaking code changes, but continues to move Swift’s syntax forward along with the APIs that it supports.

The OptionSetType makes it easy to pass multiple settings as a single parameter, without requiring you to become an expert in binary arithmetic:

// You can create custom flags or options using OptionSetType
struct VideoFormat: OptionSetType {
   let rawValue: Int
   // Use static let values within the struct and assign
   // the raw value using bitmask values (1, 2, 4, 8, 16, etc)
   static let Video1080p = VideoFormat(rawValue: 1)
   static let Video720p = VideoFormat(rawValue: 2)
   static let EnableStreaming = VideoFormat(rawValue: 4)
   static let EnableDownloads = VideoFormat(rawValue: 8)
}
// Use Swift Set notation to pass options
func startVideoPlaybackWithOptions(videoStreamOptions: [VideoFormat]) {
   print("Play video stream:", videoStreamOptions)
}
// Store a collection of options using Set notation
let videoOptions = [VideoFormat.Video1080p, VideoFormat.EnableDownloads]
startVideoPlaybackWithOptions(videoOptions)
// Set notation makes legacy bitmask operations much easier to read
if videoOptions.contains(VideoFormat.Video1080p) {
   print("Video is 1080p!")
}
download
Example playground files for Swift 2 Paul Solt/InfoWorld

Modernized SDKs and Objective-C enhancements

The last time I wrote about Swift, I wasn’t sure if Apple would continue to support Objective-C with new features. With Swift 2, Apple has proven its commitment to Objective-C.

Enhancements to Objective-C have been made to directly support writing code in Swift that calls Objective-C APIs (most of Apple’s Cocoa Touch and Cocoa SDKs).

Apple added lightweight generics to Objective-C that allow collection types to store extra type information about the elements. This provides more type safety in Objective-C, but it also means that any API using a collection type passes on the same type safety when accessed from Swift code.

The touchesBegan(_:withEvent:) method from the UIResponder protocol in Swift now supports typed collections and has been remastered for Swift 2. Take a look at the Swift syntax and API evolution from Swift 1.1 to Swift 1.2 to Swift 2.1 as Apple released fallible initializers, the Swift Set collection type, and added Objective-C’s lightweight generics:

class ViewController : UIViewController {
   // Swift 1.1 (APIs used Objective-C NSSet type)
   override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
       if let touch = touches.anyObject() asUITouch? {
           let location = touch.locationInView(self.view)
           println("Touch: \(location)")
       }
   }
   // Swift 1.2 (Swift Set introduced along with new as? keyword)
   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
       if let touch = touches.firstas? UITouch {
           let location = touch.locationInView(self.view)
           println("Touch: \(location)")
       }
   }
   // Swift 2.1 (Objective-C gains lightweight generics + Swift API update)
   override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       if let touch = touches.first {
           let location = touch.locationInView(self.view)
           print("Touch: \(location)") // New print() method
       }
   }
}
download
Example playground files for Swift 2 Paul Solt/InfoWorld

The strong type system in Swift provides enhanced type safety with compile-time checks to prevent errors before they can become runtime crashes (it is better to fix a bug early), and that’s why compile-time error checking is so important.

Apple’s other enhancements include API availability checks for compile time assertions that ensure all source code being used is supported on the current iOS version selected in Xcode. Availability is important for any company that needs to release a public SDK for app developers to integrate into their own apps. Lastly, nullability helps the Objective-C APIs work with Swift’s optional type system and makes the imported Objective-C APIs Swift-like using optional typing information.

Conclusion

Apple’s introduction of Swift 2 does break existing code, yet the latest version 2.1 (as of this writing) is a major leap forward as Swift continues to mature. These breaking code changes are vital to Swift if it is going to become an industry standard in the development world.

Swift was open-sourced in December 2015, when Apple published a road map of upcoming features for Swift 2.2. Apple has also opened the discussion to the development community for the direction of Swift 3.0 and beyond.

In Swift 2, new control flow keywords and language structures allow you to make your intentions clearer using the first line of code you write. This straightforward approach allows you to know what is happening in a block of code and improves your ability to properly maintain your app’s control flow. The guard keyword enables early exits and protects code logic from having invalid inputs. The defer keyword allows you to clean up resources when they finish or in the event of an error.

The renamed repeat/while loop and the do scoping continue to provide support for both readability and Apple’s new error handling model, which is driven by programmer intent. Any method declaration (method signature) that is potentially unsafe is marked with the new throws keyword. Any method call to an unsafe method (one that can throw errors) is marked with the new try keyword. Error handling in Swift is performant, on par with return statements, unlike Objective-C -- which is one more reason to adopt error handling using Swift for your next app project.

Along with the changes to control flow, Apple has modernized existing APIs for the OS X v10.11, iOS 9, and watchOS 2 SDKs using new language features in Objective-C that enable you to use Objective-C APIs in Swift seamlessly.

What this means for you is that the all-new Swift 2 is ready to use, and everything about it feels like Swift, even if you’re leveraging Apple’s vast Objective-C APIs and extensive SDKs. If you’re not already on board, the time is ripe to start your next app in Swift.

Related articles

1 2 Page 2
Page 2 of 2