XebiConFr 15 - Swift dans la vraie vie

Publicis Sapient Engineering
Publicis Sapient EngineeringCabinet IT à Publicis Sapient Engineering
Swift dans la vraie vie
#XebiConFr
Swift dans la vraie vie
Fabien Mirault
Développeur Objective-C / Swift
Speakers
@viteinfinite
Simone Civetta
Développeur Objective-C / Swift
@magici1
Swift ou pas ?
#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 ?
Qu’est-ce que Swift ?
#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 ?
#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
Swift ou pas ?
#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 ?
Swift c’est cool……utilisé dans de vrais projets !
#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 ?
Création du projet
#XebiConFr
Swift dans la vraie vie
Création du projet
Les dépendances
Librairies dynamiques
#XebiConFr
Swift dans la vraie vie
14
Slide Title
Title
Au revoir iOS 7
#XebiConFr
Swift dans la vraie vie
Création du projet
Les dépendances
Flux d’activités
#XebiConFr
Swift dans la vraie vie
Photos et vidéos
Fluidité
Des milliers de posts
Flux d’activités
#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
#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
#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
#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
#XebiConFr
Swift dans la vraie vie
Mapping automatique
Génère des structs
Performances accrues
JSONJoy
Flux d’activités
#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
}
#XebiConFr
Swift dans la vraie vie
Flux d’activités
Crash
Flux d’activités
#XebiConFr
Swift dans la vraie vie
Flux d’activités
Struct
Héritage Rendu
Performances
Configurations
#XebiConFr
Swift dans la vraie vie
Analytics
Endpoints
Regroupement
Profil
Configurations
#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
Liste de produits
#XebiConFr
Swift dans la vraie vie
Liste de produits
200.000+ lignes!
Requêtes rapides!
#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
#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
#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 !
}
#XebiConFr
Swift dans la vraie vie
34
Liste de produits
Generics
Écrire du code facilement réutilisable
et sujet à des contraintes spécifiques
#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
#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
}
}
#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
Synchronisation
#XebiConFr
Swift dans la vraie vie
Synchronisation
Synchronisation et
manipulation*
500 Mo de données
!
200.000+ éléments!
Performances!
#XebiConFr
Swift dans la vraie vie
Synchronisation
déclarations final et static
Profiter pleinement du dispatch statique
Performances
#XebiConFr
Swift dans la vraie vie
Synchronisation
Attention aux casts entre
Array ↔ NSArray
Dictionary ↔ NSDictionary
Performances
Tâches asynchrones
#XebiConFr
Swift dans la vraie vie
Librairie locale
Appareil photo
Ecran personnalisé
Animation diaphragme
Tâches asynchrones
#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
#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)
})
#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?
#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)
}
}
#XebiConFr
Swift dans la vraie vie
48
Tâches asynchrones
Optionals : fiabilité !
#XebiConFr
Swift dans la vraie vie
Appels asynchrones
Poster un commentaire
Sur n’importe quel post
Gestion des retours serveur
Tâches asynchrones
#XebiConFr
Swift dans la vraie vie
Tâches asynchrones
Promise
Code plus lisible
Idéal pour les tâches asynchrones
Chaînage possible
#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()
}
#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()
}
}
}
#XebiConFr
Swift dans la vraie vie
SwiftTasks
Librairie principale
Mise en place simple…
…mais des erreurs dans Xcode
#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
}
Disponibilité produit
#XebiConFr
Swift dans la vraie vie
Disponibilité produit
Simple requête HTTP!
Mise à jour de la UI!
#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)
}
#XebiConFr
Swift dans la vraie vie
Disponibilité produit
Les étapes
WebService
Déserialisation
UI
#XebiConFr
Swift dans la vraie vie
59
Disponibilité produit
Functional Reactive Programming
Propagation des changements
Flux de données
Asynchronisme
#XebiConFr
Swift dans la vraie vie
ReactiveCocoa
Reactive Cocoa
Disponibilité produit
#XebiConFr
Swift dans la vraie vie
ReactKit
github.com/ReactKit/
Disponibilité produit
#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")
#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
#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)
#XebiConFr
Swift dans la vraie vie
Disponibilité produit
Opérateurs Custom
^{
self.availabilitySpinner.stopAnimating()
self.availabilityIndicator.textColor = self.colorForStatus($0)
} <~ availabilitySignal<~
#XebiConFr
Swift dans la vraie vie
Slide Title
Title
Internationalisation
#XebiConFr
Swift dans la vraie vie
Internationalisation
Changement de la langue!
Traduction des contenus!
Traduction de l’IHM!
#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
#XebiConFr
Swift dans la vraie vie
70
Internationalisation
Enums
typedef enum : NSUInteger {
XBCountryUSA,
XBCountryChina,
XBCountryItaly
} XBCountry;
Un peu d’Objective-C
#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
#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
#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
#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
#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
#XebiConFr
Swift dans la vraie vie
Internationalisation
Enums : it’s over 9000!!
First-Class citizens
Méthodes et propriétés
Valeurs associées
Tests
#XebiConFr
Swift dans la vraie vie
Tests
Assurer le fonctionnement
de l’application
Se protéger des régressions
#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 ?
#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)
#XebiConFr
Swift dans la vraie vie
81
Slide Title
Title
#XebiConFr
Swift dans la vraie vie
82
Tests
Mais aussi…
#XebiConFr
Swift dans la vraie vie
83
Tests
Mais aussi…
#XebiConFr
Swift dans la vraie vie
84
Tests
Mais aussi…
Suivre son application
#XebiConFr
Swift dans la vraie vie
Suivre son application
Déploiement centralisé et versionné
Remontées de crashs
Statistiques d’utilisation
Fabric
#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]
#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
#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
#XebiConFr
Swift dans la vraie vie
Suivre son application
Reveal
#XebiConFr
Swift dans la vraie vie
Suivre son application
Suivre son application
Évolution du langage constante
Rétrocompatibilité non assurée
Et l’Objective-C ?
#XebiConFr
Swift dans la vraie vie
Toujours valable
Mais développement plus lent
Migration progressive conseillée
Et l’Objective-C dans tout ça ?
#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 ?
#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 ?
#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 !
#XebiConFr
Swift dans la vraie vie
#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
1 sur 98

Contenu connexe

Similaire à XebiConFr 15 - Swift dans la vraie vie

Linq et Entity frameworkLinq et Entity framework
Linq et Entity frameworkDNG Consulting
3.2K vues48 diapositives
Le Nouvel Ops XebiCon'15Le Nouvel Ops XebiCon'15
Le Nouvel Ops XebiCon'15Séven Le Mesle
754 vues146 diapositives
Formation java scriptFormation java script
Formation java scriptRomdhani Asma
614 vues47 diapositives

Similaire à XebiConFr 15 - Swift dans la vraie vie(20)

Plus de Publicis Sapient Engineering(20)

Xebicon'18 - IoT: From Edge to CloudXebicon'18 - IoT: From Edge to Cloud
Xebicon'18 - IoT: From Edge to Cloud
Publicis Sapient Engineering627 vues
XebiCon'18 - Modern InfrastructureXebiCon'18 - Modern Infrastructure
XebiCon'18 - Modern Infrastructure
Publicis Sapient Engineering541 vues
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
Publicis Sapient Engineering809 vues
XebiCon'18 - Le développeur dans la Pop Culture XebiCon'18 - Le développeur dans la Pop Culture
XebiCon'18 - Le développeur dans la Pop Culture
Publicis Sapient Engineering313 vues
XebiCon'18 - Sécuriser son API avec OpenID ConnectXebiCon'18 - Sécuriser son API avec OpenID Connect
XebiCon'18 - Sécuriser son API avec OpenID Connect
Publicis Sapient Engineering262 vues
XebiCon'18 - Spark NLP, un an aprèsXebiCon'18 - Spark NLP, un an après
XebiCon'18 - Spark NLP, un an après
Publicis Sapient Engineering4.7K vues
XebiCon'18 - La sécurité, douce illusion même en 2018XebiCon'18 - La sécurité, douce illusion même en 2018
XebiCon'18 - La sécurité, douce illusion même en 2018
Publicis Sapient Engineering268 vues

XebiConFr 15 - Swift dans la vraie vie

  • 1. Swift dans la vraie vie
  • 2. #XebiConFr Swift dans la vraie vie Fabien Mirault Développeur Objective-C / Swift Speakers @viteinfinite Simone Civetta Développeur Objective-C / Swift @magici1
  • 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 ?
  • 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. #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
  • 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. Swift c’est cool……utilisé dans de vrais projets !
  • 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 ?
  • 13. #XebiConFr Swift dans la vraie vie Création du projet Les dépendances Librairies dynamiques
  • 14. #XebiConFr Swift dans la vraie vie 14 Slide Title Title Au revoir iOS 7
  • 15. #XebiConFr Swift dans la vraie vie Création du projet Les dépendances
  • 17. #XebiConFr Swift dans la vraie vie Photos et vidéos Fluidité Des milliers de posts Flux d’activités
  • 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. #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. #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. #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. #XebiConFr Swift dans la vraie vie Mapping automatique Génère des structs Performances accrues JSONJoy Flux d’activités
  • 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. #XebiConFr Swift dans la vraie vie Flux d’activités Crash Flux d’activités
  • 25. #XebiConFr Swift dans la vraie vie Flux d’activités Struct Héritage Rendu Performances
  • 27. #XebiConFr Swift dans la vraie vie Analytics Endpoints Regroupement Profil Configurations
  • 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
  • 30. #XebiConFr Swift dans la vraie vie Liste de produits 200.000+ lignes! Requêtes rapides!
  • 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. #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. #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. #XebiConFr Swift dans la vraie vie 34 Liste de produits Generics Écrire du code facilement réutilisable et sujet à des contraintes spécifiques
  • 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. #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. #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
  • 39. #XebiConFr Swift dans la vraie vie Synchronisation Synchronisation et manipulation* 500 Mo de données ! 200.000+ éléments! Performances!
  • 40. #XebiConFr Swift dans la vraie vie Synchronisation déclarations final et static Profiter pleinement du dispatch statique Performances
  • 41. #XebiConFr Swift dans la vraie vie Synchronisation Attention aux casts entre Array ↔ NSArray Dictionary ↔ NSDictionary Performances
  • 43. #XebiConFr Swift dans la vraie vie Librairie locale Appareil photo Ecran personnalisé Animation diaphragme Tâches asynchrones
  • 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. #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. #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. #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. #XebiConFr Swift dans la vraie vie 48 Tâches asynchrones Optionals : fiabilité !
  • 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. #XebiConFr Swift dans la vraie vie Tâches asynchrones Promise Code plus lisible Idéal pour les tâches asynchrones Chaînage possible
  • 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. #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. #XebiConFr Swift dans la vraie vie SwiftTasks Librairie principale Mise en place simple… …mais des erreurs dans Xcode
  • 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 }
  • 56. #XebiConFr Swift dans la vraie vie Disponibilité produit Simple requête HTTP! Mise à jour de la UI!
  • 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. #XebiConFr Swift dans la vraie vie Disponibilité produit Les étapes WebService Déserialisation UI
  • 59. #XebiConFr Swift dans la vraie vie 59 Disponibilité produit Functional Reactive Programming Propagation des changements Flux de données Asynchronisme
  • 60. #XebiConFr Swift dans la vraie vie ReactiveCocoa Reactive Cocoa Disponibilité produit
  • 61. #XebiConFr Swift dans la vraie vie ReactKit github.com/ReactKit/ Disponibilité produit
  • 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. #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. #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. #XebiConFr Swift dans la vraie vie Disponibilité produit Opérateurs Custom ^{ self.availabilitySpinner.stopAnimating() self.availabilityIndicator.textColor = self.colorForStatus($0) } <~ availabilitySignal<~
  • 66. #XebiConFr Swift dans la vraie vie Slide Title Title
  • 68. #XebiConFr Swift dans la vraie vie Internationalisation Changement de la langue! Traduction des contenus! Traduction de l’IHM!
  • 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. #XebiConFr Swift dans la vraie vie 70 Internationalisation Enums typedef enum : NSUInteger { XBCountryUSA, XBCountryChina, XBCountryItaly } XBCountry; Un peu d’Objective-C
  • 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. #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. #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. #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. #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. #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. Tests
  • 78. #XebiConFr Swift dans la vraie vie Tests Assurer le fonctionnement de l’application Se protéger des régressions
  • 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. #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. #XebiConFr Swift dans la vraie vie 81 Slide Title Title
  • 82. #XebiConFr Swift dans la vraie vie 82 Tests Mais aussi…
  • 83. #XebiConFr Swift dans la vraie vie 83 Tests Mais aussi…
  • 84. #XebiConFr Swift dans la vraie vie 84 Tests Mais aussi…
  • 86. #XebiConFr Swift dans la vraie vie Suivre son application Déploiement centralisé et versionné Remontées de crashs Statistiques d’utilisation Fabric
  • 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. #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. #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. #XebiConFr Swift dans la vraie vie Suivre son application Reveal
  • 91. #XebiConFr Swift dans la vraie vie Suivre son application Suivre son application Évolution du langage constante Rétrocompatibilité non assurée
  • 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. #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. #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. #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 !
  • 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