Xcode 8.0 and SDK 10 bring swift 3.0 with it! You certainly didn't have the opportunity to start a brand new project on it yet, so let's talk about the migration, it's steps and the issues encountered.
▸ Only takes advantage of Nullability Checking on Objective-C Interoperability // Swift 2.2 let image = CIImage(MTLTexture: texture, options: options) let extent = image.extent // this code can lead to a crash // Swift 3.0 if let image = CIImage(MTLTexture: texture, options: options) { … } ▸ This can help you migrate quickly to the SDK 10 on a big base code % 5
▸ Xcode loses code sense (even more than usual) ▸ Sometimes completion code is absent / No code coloration when lost ▸ When showing real-time errors in source code, Xcode can get lost ▸ this is valid swift 2.3 code ! and it builds ▸ fixed in latest Xcode 8.2.1 ▸ Xcode 8.2.x is the last version to support it! 6
COCOAPODS / CARTHAGE ▸ Long live Objective-C! ▸ Almost nothing to do here… ▸ Some authors have annotated their libraries: better swift interoperability! ▸ Others have created a brand new swift version: ▸ MMDrawerController has been converted to DrawerController drawerController?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.None [X] ’None' has been renamed to 'none' 12 https://github.com/mutualmobile/MMDrawerController/issues/476 drawerController?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.none [X] 'none' is unavailable: use [] to construct an empty option set
▸ SwiftLint - https://github.com/realm/SwiftLint 1. Launch the migration assistant on your targets only 2. Analyse each source file: 1. Fix it if needed 2. Uncheck from migration when it’s a third party file 3. Do not hesitate to pass the migrator several times LET’S MIGRATE - SWIFT 3.0 3. SOME OTHER THINGS
_ is automatically added, you probably want to name them properly func updateIdentityWithName(_ name: String, firstname: String) throws ▸ Some Foundation objects with deleted NS prefix are casted to conform to new APIs let url = NSURL(string: "http://someurl.com" ) URLComponents(url: url as URL, resolvingAgainstBaseURL: false) REAL WORLD PROBLEMS BEWARE SOME CHANGES ARE MADE AUTOMATICALLY SE-0046 if let url = URL(string: "http://someurl.com" ) { URLComponents(url: url, resolvingAgainstBaseURL: false) } func updateIdentity(name: String, firstname: String) throws
new APIs accept Any ▸ Convert your JSON objects to [String: Any] ▸ ⚠ Some types becomes values types! ▸ public struct Date versus open class NSDate ▸ But it can simplify the reading: ▸ (x as NSDate).earlierDate(y) can be changed to x < y ? x : y REAL WORLD PROBLEMS BEWARE SOME CHANGES ARE MADE AUTOMATICALLY https://developer.apple.com/swift/blog/?id=39
absoluteString will not be removed, it’s your job ▸ Tip: If you absolutely need to keep your code block you can use a do statement REAL WORLD PROBLEMS SOME APIS DO NOT RETURN OPTIONALS ANYMORE open class NSURL { open var absoluteString: String? { get } } public struct URL { public var absoluteString: String { get } } versus do { //your code here }
operators with optionals were removed from the Swift Standard Libary. // Consider refactoring the code to use the non-optional operators. fileprivate func > <T: Comparable>(lhs: T?, rhs: T?) -> Bool { switch (lhs, rhs) { case let (l?, r?): return l > r default: return rhs < lhs } }
at that time using Xcode 8.0) DispatchQueue.global(qos: .background).async { //do some work } DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 1) { //do some work in 1s from now } ▸ dispatch_once doesn’t exist anymore ▸ Use lazily initialised globals or static properties REAL WORLD PROBLEMS GRAND CENTRAL DISPATCH SE-0044 & SE-0088
ImplicitlyUnwrappedOptionals are considered like optionals now, but not all the time REAL WORLD PROBLEMS OBJECTIVE-C INTEROPERABILITY https://www.natashatherobot.com/swift-3-implicitly-unwrapped-optionals/ because File > New Project is a rare thing func valueUp(value: Int!) { // oldValue is an Int? // since value doesn't need to be type checked let oldValue = value // Int? // newValue is an Int, // since value was forced to unwrap // b/c it had to be type checked to do the addition let newValue = value + 1 // Int […] } valueUp(value: 10)
APIs automatically " ▸ Legacy swift annotations are still available ▸ nullability / generics ▸ NS_SWIFT_NAME / NS_REFINED_FOR_SWIFT / NS_SWIFT_UNAVAILABLE ▸ New annotations available ▸ NS_NOESCAPE to annotate your objective-c blocks (eg. @noespace) ▸ NSEXTENSIBLESTRING_ENUM to convert a string based obj-c enum to a struct REAL WORLD PROBLEMS OBJECTIVE-C INTEROPERABILITY https://realm.io/news/altconf-nikita-lutsenko-objc-swift-interoperability/ because File > New Project is a rare thing
▸ OptionSet are not converted as expected for default values : ▸ UIControlState() instead of .normal : it works but less readable ▸ Visibility changes : private becomes fileprivate etc… ▸ ⚠ Be aware of open versus public on your libraries REAL WORLD PROBLEMS SOME RANDOM NOTES SE-0067
▸ let list = Array(myLazyCollection) if you really need a Collection ▸ New compiler : new warnings like unused results ▸ You can add _ to discard it: _ = foo() ▸ returned result is secondary: @discardableResult on the function can also avoid this warning REAL WORLD PROBLEMS SOME RANDOM NOTES SE-0067