XebiConFr 15 - Swift dans la vraie vie

600 vues

Publié le

Au cours de "Swift dans la vraie vie" vous assisterez à un retour d'expérience concernant l'utilisation du dernier langage d'Apple - maintenant Open Source - dans deux projets mobiles utilisés en production par quelques milliers d'utilisateurs.

À travers une analyse des points de force et faiblesse de ce langage, vous comprendrez pourquoi il n'est pas trop osé de commencer tout de suite à développer votre prochaine application iOS en Swift.

Par Simone Civetta et Fabien Mirault, consultants chez Xebia

La vidéo de la conférence est à retrouver sur : http://www.xebicon.fr/programme.html

Publié dans : Logiciels
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
600
Sur SlideShare
0
Issues des intégrations
0
Intégrations
8
Actions
Partages
0
Téléchargements
0
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

XebiConFr 15 - Swift dans la vraie vie

  1. 1. Swift dans la vraie vie
  2. 2. #XebiConFr Swift dans la vraie vie Fabien Mirault Développeur Objective-C / Swift Speakers @viteinfinite Simone Civetta Développeur Objective-C / Swift @magici1
  3. 3. Swift ou pas ?
  4. 4. #XebiConFr Swift dans la vraie vie Septembre 2014 Octobre 2014 Novembre 2014 Juin 2014 Apple annonce Swift ! Swift 1.0 ! Première application Swift Xebia sur l’App Store Swift 1.1 ? Janvier 2015 Nouvelles applications ? Swift ou pas ?
  5. 5. Qu’est-ce que Swift ?
  6. 6. #XebiConFr Swift dans la vraie vie Nouveau langage de développement Code plus lisible et moins verbeux Donc plus simple à maintenir ! Qu’est-ce que Swift ?
  7. 7. #XebiConFr Swift dans la vraie vie Qu’est-ce que Swift ? Transition Objective-C → Swift aisée Moins de tolérance sur les erreurs de code Rapidité de développement accrue
  8. 8. Swift ou pas ?
  9. 9. #XebiConFr Swift dans la vraie vie Septembre 2014 Octobre 2014 Novembre 2014 Juin 2014 Apple annonce Swift ! Swift 1.0 ! Première application Xebia sur l’App Store Swift 1.1 ? Janvier 2015 Nouvelles applications ! ! Swift ou pas ?
  10. 10. Swift c’est cool……utilisé dans de vrais projets !
  11. 11. #XebiConFr Swift dans la vraie vie TOC Nos cas d’usage Flux d’activité Création du projet et configuration Produits et synchronisation Langues Commentaires Testing Suivre son application Et l’Objective-C ?
  12. 12. Création du projet
  13. 13. #XebiConFr Swift dans la vraie vie Création du projet Les dépendances Librairies dynamiques
  14. 14. #XebiConFr Swift dans la vraie vie 14 Slide Title Title Au revoir iOS 7
  15. 15. #XebiConFr Swift dans la vraie vie Création du projet Les dépendances
  16. 16. Flux d’activités
  17. 17. #XebiConFr Swift dans la vraie vie Photos et vidéos Fluidité Des milliers de posts Flux d’activités
  18. 18. #XebiConFr Swift dans la vraie vie Ne contient que ce qui a été défini Meilleures performances Stockage de type valeur et non référence Struct Flux d’activités
  19. 19. #XebiConFr Swift dans la vraie vie Flux d’activités Exemple de Struct public struct Attachment { public let id: Int public let url: String public let type: String public let name: String public let objectId: Int public let mimeType: String public let objectType: String } Flux d’activités
  20. 20. #XebiConFr Swift dans la vraie vie Struct : Performances Flux d’activités Avec une méthode de shuffle sur 1.000.000 d’objets Secondes 0 0,325 0,65 0,975 1,3 NSObject Struct 0,064 1,152
  21. 21. #XebiConFr Swift dans la vraie vie Flux d’activités Struct VS Classes Ne peut pas hériter d’objets Pas de deinitializer Référence unique d’une instance
  22. 22. #XebiConFr Swift dans la vraie vie Mapping automatique Génère des structs Performances accrues JSONJoy Flux d’activités
  23. 23. #XebiConFr Swift dans la vraie vie Flux d’activités JSONJoy par l’exemple private static func buildUser(userData:[String: AnyObject]) -> User? { ... let user = User(JSONDecoder(userData)) return user }
  24. 24. #XebiConFr Swift dans la vraie vie Flux d’activités Crash Flux d’activités
  25. 25. #XebiConFr Swift dans la vraie vie Flux d’activités Struct Héritage Rendu Performances
  26. 26. Configurations
  27. 27. #XebiConFr Swift dans la vraie vie Analytics Endpoints Regroupement Profil Configurations
  28. 28. #XebiConFr Swift dans la vraie vie Configurations struct Tags { struct Page { static let Login = "Login" static let Camera = "Camera" static let Newsfeed = "Newsfeed" static let Favorites = "Favorites" static let MyProfile = "MyProfile" static let OtherProfile = "OtherProfile" static let LiveSessions = "LiveSessions" static let CreateAccount = "CreateAccount" static let ForgottenPassword = "ForgottenPassword" } } Configurations
  29. 29. Liste de produits
  30. 30. #XebiConFr Swift dans la vraie vie Liste de produits 200.000+ lignes! Requêtes rapides!
  31. 31. #XebiConFr Swift dans la vraie vie Liste de produits @implementation XBEntityStore - (void)addEntity:(id<XBEntity>)entity { // Some implementation } @end ... Un peu d’Objective-C - (void)addSomeObjects { XBEntityStore *productStore = [XBEntityStore new]; // XBProduct conforms to XBEntity XBProduct *product = [XBProduct new]; [productStore addEntity:product]; } Stockage : Objective-C
  32. 32. #XebiConFr Swift dans la vraie vie - (void)addSomeObjects { XBEntityStore *productStore = [XBEntityStore new]; // XBProduct conforms to XBEntity XBProduct *product = [XBProduct new]; [productStore addEntity:product]; // XBColor conforms to XBEntity XBColor *color = [XBColor new]; [productStore addEntity:color]; } 32 Liste de produits Stockage : Objective-C @implementation XBEntityStore - (void)addEntity:(id<XBEntity>)entity { // Some implementation } @end ... Un peu d’Objective-C
  33. 33. #XebiConFr Swift dans la vraie vie 33 Liste de produits Generics class EntityStore<T: Entity> { func addEntity(entity: T) { // Some implementation } } ... func addSomeObjects() { let productStore = EntityStore<Product>() // Product conforms to Entity let product = Product() productStore.addEntity(product) // Color conforms to Entity let color = Color() productStore.addEntity(color) } Un peu de Swift func addSomeObjects() { let productStore = EntityStore<Product>() // Product conforms to Entity let product = Product() productStore.addEntity(product) // Color conforms to Entity let color = Color() productStore.addEntity(color) // Ne compile pas ! }
  34. 34. #XebiConFr Swift dans la vraie vie 34 Liste de produits Generics Écrire du code facilement réutilisable et sujet à des contraintes spécifiques
  35. 35. #XebiConFr Swift dans la vraie vie 35 Liste de produits TypeAlias typealias ProductStore = EntityStore<Product> func addSomeObjects() { let productStore = ProductStore() // Product conforms to Entity let product = Product() productStore.addEntity(product) } typealias ColorStore = EntityStore<Color> func addSomeObjects() { let colorStore = ColorStore() // Color conforms to Entity let color = Color() colorStore.addEntity(product) } Code plus expressif
  36. 36. #XebiConFr Swift dans la vraie vie 36 Liste de produits Protocols Swift est un “langage orienté protocoles” Apple, 2015 protocol Entity { } class EntityStore<T: Entity> { func addEntity(entity: T) { // Some implementation } }
  37. 37. #XebiConFr Swift dans la vraie vie 37 Liste de produits Swift VS Swift class EntityStore { func addEntity(entity: Entity) { // Some implementation } } func addSomeObjects() { let productStore = EntityStore() let product = Product() productStore.addEntity(product) } Coder Swift != Penser Swift class EntityStore<T: Entity> { func addEntity(entity: T) { // Some implementation } } func addSomeObjects() { let productStore = ProductStore() let product = Product() productStore.addEntity(product) } Generics Typealias
  38. 38. Synchronisation
  39. 39. #XebiConFr Swift dans la vraie vie Synchronisation Synchronisation et manipulation* 500 Mo de données ! 200.000+ éléments! Performances!
  40. 40. #XebiConFr Swift dans la vraie vie Synchronisation déclarations final et static Profiter pleinement du dispatch statique Performances
  41. 41. #XebiConFr Swift dans la vraie vie Synchronisation Attention aux casts entre Array ↔ NSArray Dictionary ↔ NSDictionary Performances
  42. 42. Tâches asynchrones
  43. 43. #XebiConFr Swift dans la vraie vie Librairie locale Appareil photo Ecran personnalisé Animation diaphragme Tâches asynchrones
  44. 44. #XebiConFr Swift dans la vraie vie Tâches asynchrones Equivalent des blocks en Objective-C Comprend un bloc de code à exécuter Définition : {  ()  -­‐>  ()  in  } Closure
  45. 45. #XebiConFr Swift dans la vraie vie Tâches asynchrones Exemple de closure self.closeDiaphragm(duration:0.3, completionBlock: { finished in self.openDiaphragm(duration:0.3) })
  46. 46. #XebiConFr Swift dans la vraie vie Tâches asynchrones Optional Possède une valeur ou non Sécurise le code Tester la non nullité : if  let Définition : var  delegate:CameraDelegate?
  47. 47. #XebiConFr Swift dans la vraie vie Tâches asynchrones Exemple d’optionals func setup(image:UIImage?) { if let menuIcon = image { let menuImageView = UIImageView(image: menuIcon) self.addSubview(menuImageView) } }
  48. 48. #XebiConFr Swift dans la vraie vie 48 Tâches asynchrones Optionals : fiabilité !
  49. 49. #XebiConFr Swift dans la vraie vie Appels asynchrones Poster un commentaire Sur n’importe quel post Gestion des retours serveur Tâches asynchrones
  50. 50. #XebiConFr Swift dans la vraie vie Tâches asynchrones Promise Code plus lisible Idéal pour les tâches asynchrones Chaînage possible
  51. 51. #XebiConFr Swift dans la vraie vie Tâches asynchrones Exemple de Promise // Parameters var parameters = Parameters() parameters["content"] = view.textView.text PostRequest.getHeaders() .success { token in return PostRequest.postContent(token, parameters) } .success { data in sendComplete() } .failure { (error, isCancelled) -> Void in sendFailed() }
  52. 52. #XebiConFr Swift dans la vraie vie Tâches asynchrones Sans Promise // Parameters var parameters = Parameters() parameters["content"] = view.textView.text PostRequest.getHeaders() { [weak self] (token:String, error:NSError) -> Void in if token != nil { PostRequest.postContent(token, parameters) { [weak self] (result:Bool, error:NSError) -> Void in if result == true { if let strongSelf == self { strongSelf.sendComplete() } } else { if let strongSelf == self { strongSelf.sendFailed() } } } } else { if let strongSelf == self { strongSelf.sendFailed() } } }
  53. 53. #XebiConFr Swift dans la vraie vie SwiftTasks Librairie principale Mise en place simple… …mais des erreurs dans Xcode
  54. 54. #XebiConFr Swift dans la vraie vie Tâches asynchrones Erreurs avec Xcode if let colorsFilePath = syncDataConfiguration.colorsFile, data = NSData(contentsOfFile:colorsFilePath) { MetadataJSONDeserializer.deserialize(data, keyPath: "colors.color") .success { color -> ColorDuplicateRemovalTask in return self.removeDuplicateIdentifiers(colors) } .success { colors -> JSONInsertTask in return entityStore.replaceAllObjects(colors, transformer: Color.tranform) } .success { JSONs -> Void in taskTuple.fulfill(JSONs) } .failure { (error, isCancelled) in if let error = error { taskTuple.reject(error) } } return taskTuple.task }
  55. 55. Disponibilité produit
  56. 56. #XebiConFr Swift dans la vraie vie Disponibilité produit Simple requête HTTP! Mise à jour de la UI!
  57. 57. #XebiConFr Swift dans la vraie vie Disponibilité produit Alamofire Alamofire.request(URLRequest) .validate() .response { (request, response, data, error) in print(request) print(response) print(data) print(error) }
  58. 58. #XebiConFr Swift dans la vraie vie Disponibilité produit Les étapes WebService Déserialisation UI
  59. 59. #XebiConFr Swift dans la vraie vie 59 Disponibilité produit Functional Reactive Programming Propagation des changements Flux de données Asynchronisme
  60. 60. #XebiConFr Swift dans la vraie vie ReactiveCocoa Reactive Cocoa Disponibilité produit
  61. 61. #XebiConFr Swift dans la vraie vie ReactKit github.com/ReactKit/ Disponibilité produit
  62. 62. #XebiConFr Swift dans la vraie vie Disponibilité produit Functional Reactive Programming ^{ let available = $0 as! Bool self.availabilitySpinner.stopAnimating() self.availabilityIndicator.textColor = self.colorForStatus(available) } <~ KVO.signal(viewModel, "status")
  63. 63. #XebiConFr Swift dans la vraie vie [[[RACObserve(viewModel.status) map:^id(NSString *status) { if ([status isKindOfClass:[NSString class]]) { return status; } return nil; }] map:^id(NSString *status) { return @([status isEqualToString:@“available"]); }] delay:1.0]; [[[RACObserve(viewModel.status) map:^id(NSString *status) { if ([status isKindOfClass:[NSString class]]) { return status; } return nil; }] map:^id(NSString *status) { return @([status isEqualToString:@“available"]); }] delay:1.0]; Disponibilité produit FRP - Objective-C
  64. 64. #XebiConFr Swift dans la vraie vie Disponibilité produit FRP - Swift let availabilitySignal = KVO.signal(viewModel, "status") .map { status -> String? in return status as? String } .map { status -> Bool in return status == "available" } .delay(1.0)
  65. 65. #XebiConFr Swift dans la vraie vie Disponibilité produit Opérateurs Custom ^{ self.availabilitySpinner.stopAnimating() self.availabilityIndicator.textColor = self.colorForStatus($0) } <~ availabilitySignal<~
  66. 66. #XebiConFr Swift dans la vraie vie Slide Title Title
  67. 67. Internationalisation
  68. 68. #XebiConFr Swift dans la vraie vie Internationalisation Changement de la langue! Traduction des contenus! Traduction de l’IHM!
  69. 69. #XebiConFr Swift dans la vraie vie Internationalisation self.headerLabel.text = NSLocalizedString("Header.Title", comment: "Header Title") extension UILabel { var localizedText: String { set { self.text = NSLocalizedString(newValue, comment: newValue) } /* ... */ } } self.headerLabel.localizedText = "Header.Title" Extensions
  70. 70. #XebiConFr Swift dans la vraie vie 70 Internationalisation Enums typedef enum : NSUInteger { XBCountryUSA, XBCountryChina, XBCountryItaly } XBCountry; Un peu d’Objective-C
  71. 71. #XebiConFr Swift dans la vraie vie 71 Internationalisation Enums enum Country: String { case USA = "US" case China = "CN" case Italy = "IT" } Et finalement du Swift Valeurs associées
  72. 72. #XebiConFr Swift dans la vraie vie 72 Internationalisation Enums enum Country: String { case USA = "US" case China = "CN" case Italy = "IT" static var defaultCountry: Country { return Country.Italy } } Country.defaultCountry Et finalement du Swift Valeurs associées Propriétés
  73. 73. #XebiConFr Swift dans la vraie vie 73 Internationalisation Switch enum Language { case English(region: String) case Italian var name: String { switch self { case .English(let region): return "English " + region case .Italian: return "Italian" } } } Swift
  74. 74. #XebiConFr Swift dans la vraie vie 74 Internationalisation Switch enum Language { case English(region: String) case Italian var name: String { switch self { case .English(let region): return "English " + region case .Italian: return "Italian" } } } Swift Pattern matching
  75. 75. #XebiConFr Swift dans la vraie vie enum Language { case English(region: String) case Italian var name: String { switch self { case .English(let region) where region == "US": return "English Default” case .English(let region): return "English " + region case .Italian: return "Italian" } } 75 Internationalisation Switch Swift Pattern matching Switch exhaustif
  76. 76. #XebiConFr Swift dans la vraie vie Internationalisation Enums : it’s over 9000!! First-Class citizens Méthodes et propriétés Valeurs associées
  77. 77. Tests
  78. 78. #XebiConFr Swift dans la vraie vie Tests Assurer le fonctionnement de l’application Se protéger des régressions
  79. 79. #XebiConFr Swift dans la vraie vie Tests Stockage des produits static func processProducts(products: [Product]) { products.filter { ... } Stores.ProductStore.insertObjects(products) } ... processProducts(myProducts) func testProcessProducts() { // Setup let products = [Product("A"), Product("B")] let productManager = ProductManager() // Run productManager.processProducts(products) // Verify // ?? } Comment tester ?
  80. 80. #XebiConFr Swift dans la vraie vie 80 Tests Stockage des produits func testProcessProducts() { // Setup let products = [Product("A"), Product("B")] let mockProductStore = ProductStore(coordinator: MockCoordinator()) let productManager = ProductManager() // Run productManager.processProducts(products, productStore: mockProductStore) // Verify XCTAssertEqual(productStore.allObjects().count, 2) } func processProducts(products: [Product], productStore: ProductStore = ProductStore()) { products.filter { ... } productStore.insertObjects(products) } ... processProducts(myProducts)
  81. 81. #XebiConFr Swift dans la vraie vie 81 Slide Title Title
  82. 82. #XebiConFr Swift dans la vraie vie 82 Tests Mais aussi…
  83. 83. #XebiConFr Swift dans la vraie vie 83 Tests Mais aussi…
  84. 84. #XebiConFr Swift dans la vraie vie 84 Tests Mais aussi…
  85. 85. Suivre son application
  86. 86. #XebiConFr Swift dans la vraie vie Suivre son application Déploiement centralisé et versionné Remontées de crashs Statistiques d’utilisation Fabric
  87. 87. #XebiConFr Swift dans la vraie vie Suivre son application Fabric - Objective-C RTSViewController.m line 1310 -[RTSViewController getCurrentUDPValues] Fatal Exception: NSRangeException *** -[__NSArrayM objectAtIndex:] index 4294967292 beyond bounds [0 .. 511]
  88. 88. #XebiConFr Swift dans la vraie vie Suivre son application Fabric - Swift WSClient.swift line 31 static MyLittlePony.WSClient.requestContent (MyLittlePony.WSClient.Type) parameters : Swift.Optional <Swift.Dictionary <Swift.String, Swift.AnyObject> Crashed: com.apple.main-thread SIGABRT ABORT at 0x312a8df0
  89. 89. #XebiConFr Swift dans la vraie vie Suivre son application Reveal Vue éclatée Fonctionne sur simulateur ou device Édition à la volée des propriétés
  90. 90. #XebiConFr Swift dans la vraie vie Suivre son application Reveal
  91. 91. #XebiConFr Swift dans la vraie vie Suivre son application Suivre son application Évolution du langage constante Rétrocompatibilité non assurée
  92. 92. Et l’Objective-C ?
  93. 93. #XebiConFr Swift dans la vraie vie Toujours valable Mais développement plus lent Migration progressive conseillée Et l’Objective-C dans tout ça ?
  94. 94. #XebiConFr Swift dans la vraie vie Popularitédesrecherches 2014 2015 Objective-C Swift Objective-C Swift Source : TIOBE 3 ème 19 ème 14 ème 15 ème Et l’Objective-C dans tout ça ?
  95. 95. #XebiConFr Swift dans la vraie vieNouveaux Repositories entre Q3 et Q4 2014 Swift Objective-C 97 3757 Source : http://githut.info Et l’Objective-C dans tout ça ?
  96. 96. #XebiConFr Swift dans la vraie vie Les avantages de Swift Plus facile à maintenir et plus robuste Demande moins de code Soyez acteur des évolutions d’Apple !
  97. 97. #XebiConFr Swift dans la vraie vie
  98. 98. #XebiConFr Swift dans la vraie vie Un peu de lecture A Swift Kickstart
 Daniel Steinberg Functional Programming in Swift
 Chris Eidhof, Florian Kugler, and Wouter Swierstra http://blog.xebia.fr/tag/swift L’équipe iOS Xebia Advanced Swift
 Chris Eidhof and Airspeed Velocity

×