Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Migration Swift, encore : de 2 à 3

Migration Swift, encore : de 2 à 3

Présentée lors du Cocoaheads Montréal du 15 décembre 2016 dans les locaux de Breather

Jean-Francois Duval

December 15, 2016
Tweet

Other Decks in Technology

Transcript

  1. La marche du progrès est inéluctable • Abandon du support

    de Swift 2.3 avec Xcode 8.3 • Globalement Swift 3 est très agréable à utiliser • Tournant majeur vers la stabilité • Dernière grosse migration selon Chris Lattner
  2. De où partir • Pas de gros changement de paradigme

    avec Swift 3 • « We’re programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We’re not excited by incremental renovation: tinkering, improving, planting flower beds. »
  3. S’organiser • La migration ne peut pas se faire en

    morceau • En fonction du projet ça peut prendre de quelques heures à plusieurs semaines. • Les équipes pourraient avoir a envisager un « code freeze » • Nous on a en pas eu besoin, la migration nous a prit que quelques heures • …a condition de défricher le terrain avant ;)
  4. Dépendances • Les libs doivent être dispo en Swift 3

    • Ce n’est pas toujours officiellement le cas • Dans certains cas les libs peuvent demander certaine adaptations a votre projet, ex: Alamofire 4 pod 'CoolLib', :git => 'https://github.com/coollib', :branch => 'swift3' • installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '3.0' end end
  5. Xcode Migration Assistant • 4000 lignes modifiées sur 26000 lignes

    de Swift • Beaucoup + une fois que le code respectera toutes les guidelines de Swift 3 • Ne pas l’appliquer aux libs !
  6. Le Xcode Migration Assistant est loin d’être parfait placesClient?.lookUpPlaceID(identifier, callback:

    { (place: GMSPlace?, error: NSError?) -> Void in // awesome code }) placesClient?.lookUpPlaceID(identifier, callback: { (place, error) -> Void in // awesome code }) placesClient?.lookUpPlaceID(identifier, callback: { (place: GMSPlace?, error: NSError?) -> Void in // awesome code } as! GMSPlaceResultCallback)
  7. Hand audit • +2000 lignes, ce qui n’inclut que l’essentiel

    pour que le projet compile • Total 6000 lignes pour une migration fonctionnelle • A suivre, Swift 3 API Design Guideline, ex : // Swift 2 func requestForPath(path: String) -> NSURLRequest // May become in Swift 3 func request(path: String) -> URLRequest
  8. Never ending story • Patience • Patience • Patience •

    Patience • Patience • Patience • Patience
  9. • Concis • API Pruning • Arguments nommés cohérents Sexy

    syntax class func darkGrayColor() -> UIColor // so foregroundColor = .darkGrayColor() // becomes foregroundColor = .darkGray
  10. ObjC interoperability horrors • Explicit Bridging Conversion • Swift extensions

    // Before Swift 3 "/bla/bla/bla".lastPathComponent // Swift 3 ("/bla/bla/bla" as NSString).lastPathComponent
  11. • Unused result • _ = self.navigation…… • • l’invasion

    des _ SwiftSR-1681 spurious "unused result" warning in Swift 3 @objc(mailComposeController:didFinishWithResult:error:) func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: NSError?) { // do something } @discardableResult func foo(bar: Int) => func foo(_ bar: Int)
  12. • The migrator may not fully migrate closures that take

    ImplicitlyUnwrappedOptionals. ◦ Workaround: Promote them to use regular optionals. • The migrator may incorrectly insert ? after values of implicitly unwrapped optional type where ! would be more appropriate. This can allow a nil value to be silently propagated instead of deterministically trapping. ◦ Workaround: Use ! instead of ? in these cases when you desire nil values to trap. • The migrator will not migrate if let statements which no longer return optional. ◦ Workaround: Remove the statement from the if let statement. If you need to keep a lexical scope, bring the binding inside a do statement. • The migrator does not add leading dots to enum cases. This can cause conflicts when the migrator lowercases them. ◦ Workaround: Manually add leading dots to enum cases that don’t already have them. • Properties whose name conflicts with Foundation types after removing their NS prefix will lead to module- qualified type names. For example, if there is a var URL: NSURL, it will be rewritten as var URL: Foundation.URL ◦ Workaround: Rename these properties before migration, so they don’t conflict. The Swift API guidelines suggest they should be lowercased. • Enums whose raw types are String may require manual renaming to follow the new Swift naming guideline. • The migrator may add unnecessary Swift module qualifications to SequenceType conformances, e.g. struct MySequence: SequenceType => struct MySequence: Swift.Sequence. ◦ Workaround: Remove the leading Swift. https://swift.org/migration-guide/
  13. « Quand on ne peut plus freiner une machine qui

    se dirige droit vers un mur, la seule solution est de foncer. »