let's migrate to swift 3.0

27
LET’S MIGRATE TO 3.0 COCOAHEADS NANTES David Bonnet - @iGranDav 19 January 2017

Upload: cocoaheads-france

Post on 12-Apr-2017

944 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Let's migrate to Swift 3.0

LET’S MIGRATE TO 3.0COCOAHEADS NANTES

David Bonnet - @iGranDav

19 January 2017

Page 2: Let's migrate to Swift 3.0

A LITTLE BIT OF HISTORY…

▸ From Swift 1.x to Swift 2.x

▸ Just remember ErrorType and throwable types

▸ Swift 3.0 is the first community version !

🎉 " ‣ it also breaks code ! 😅

Page 3: Let's migrate to Swift 3.0

⚠STILL NOT ABI STABLE !

Everything needs to be migrated

Page 4: Let's migrate to Swift 3.0

LET’S DO IT SOFTLYSWIFT 2.3

Page 5: Let's migrate to Swift 3.0

LET’S DO IT SOFTLY - SWIFT 2.3

A LIGHTWEIGHT UPDATE

▸ 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

Page 6: Let's migrate to Swift 3.0

LET’S DO IT SOFTLY - SWIFT 2.3

A TEMPORARY SOLUTION

▸ 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

Page 7: Let's migrate to Swift 3.0

OK NOW FOR REALSWIFT 3.0

Page 8: Let's migrate to Swift 3.0

APPLE SOLUTIONLET’S MIGRATE - SWIFT 3.0

Page 9: Let's migrate to Swift 3.0

LET’S MIGRATE - SWIFT 3.0

APPLE SOLUTION - MIGRATION ASSISTANT

9

Page 10: Let's migrate to Swift 3.0

LET’S MIGRATE - SWIFT 3.0

APPLE SOLUTION - MIGRATION ASSISTANT IN REAL LIFE

10

😱Using Xcode 8.0

Page 11: Let's migrate to Swift 3.0

AN APPROACHLET’S MIGRATE - SWIFT 3.0

Page 12: Let's migrate to Swift 3.0

LET’S MIGRATE - SWIFT 3.0

1. MIGRATE YOUR DEPENDENCIES - 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

Page 13: Let's migrate to Swift 3.0

LET’S MIGRATE - SWIFT 3.0

1. MIGRATE YOUR DEPENDENCIES - COCOAPODS / CARTHAGE

▸ ⚠ update your libraries means update also their APIs or introduce new features! extension Results {

func toArray() -> [T] { return self.map {$0} } }

extension RealmSwift.List {

func toArray() -> [T] { return self.map {$0} } }

13

=>//New definition in RxRealm extension List: NotificationEmitter { public typealias ElementType = Element public func toArray() -> [Element] { return Array(self) } }

Page 14: Let's migrate to Swift 3.0

14

▸ Migrate your code template before the migration!

▸ SwiftGen - https://github.com/AliSoftware/SwiftGen

-t swift3

LET’S MIGRATE - SWIFT 3.0

2. USING A CODE GENERATOR?

#!/bin/sh swiftgen strings

Page 15: Let's migrate to Swift 3.0

15

▸ Use a linter? Disable it during the migration.

▸ 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

Page 16: Let's migrate to Swift 3.0

REAL WORLD PROBLEMSSHARING ISSUES AND FIXING THEM +

Page 17: Let's migrate to Swift 3.0

17

▸ To avoid renaming all your APIs calls:

▸ _ 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

Page 18: Let's migrate to Swift 3.0

18

▸ A cast to AnyObject is frequently added although 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

Page 19: Let's migrate to Swift 3.0

19

▸ Your potential if let or guard let on 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

}

Page 20: Let's migrate to Swift 3.0

REAL WORLD PROBLEMS

OPTIONAL COMPARATORS DISAPPEARED

20

// FIXME: comparison 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 } }

Page 21: Let's migrate to Swift 3.0

21

▸ Dispatch APIs are not correctly migrated (at least 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

Page 22: Let's migrate to Swift 3.0

22

▸ Remember Nullability Checking integrated into Swift 2.3

▸ 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)

Page 23: Let's migrate to Swift 3.0

23

▸ Swift 3 renamed a lot of objective-c based 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

Page 24: Let's migrate to Swift 3.0

24

▸ I had to convert manually CGFloat.max to CGFloat.greatestFiniteMagnetude

▸ 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

Page 25: Let's migrate to Swift 3.0

25

▸ map or flatmap returns LazyCollection types now :

▸ 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

Page 26: Let's migrate to Swift 3.0

QUESTION TIMETHANKS FOR YOUR ATTENTION 😀

Page 27: Let's migrate to Swift 3.0

27

▸ A (mostly) comprehensive list of Swift 3.0 and 2.3 changes

▸ https://buildingvts.com/a-mostly-comprehensive-list-of-swift-3-0-and-2-3-changes-193b904bb5b1

▸ Swift migration guide

▸ https://swift.org/migration-guide/

▸ WWDC 2016 - Session 402 : What’s new in swift

▸ https://developer.apple.com/videos/play/wwdc2016/402/

▸ AltConf - Advanced ObjC <-> Swift Interoperability

▸ https://realm.io/news/altconf-nikita-lutsenko-objc-swift-interoperability/

LET’S MIGRATE TO 3.0

REFERENCES

David Bonnet - @[email protected]