Devoxx 17 - Swift server-side

298 vues

Publié le

Quand Swift a été annoncé en 2014, personne n'aurait imaginé qu'un jour on aurait pu se servir de ce langage pour réaliser une application... côté serveur !

Ce talk a pour but de démontrer comment et dans quelle mesure nous pouvons écrire et deployer une application Web en utilisant Swift 3.0, en utilisant les plates-formes proposées par le marché. Nous découvrirons également les forces et faiblesses actuelles, les frameworks et les outils à utiliser aujourd'hui, ainsi que les extensions pour connecter notre application Swift côté serveur à des services tierces, tels que les systèmes de gestion de base de données.

Par Simone Civetta, Développeur iOS chez Xebia.

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

  • Soyez le premier à aimer ceci

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

Aucune remarque pour cette diapositive

Devoxx 17 - Swift server-side

  1. 1. Swi! Côté Serveur 1
  2. 2. Salut 2
  3. 3. Simone Cive!a3
  4. 4. Je suis un développeur iOS 4
  5. 5. 7ans 5
  6. 6. 6
  7. 7. 4ans 7
  8. 8. 8
  9. 9. 9
  10. 10. 10
  11. 11. 11
  12. 12. 12
  13. 13. 13
  14. 14.           Enfin...           14
  15. 15. Plan1. Les Origines 2. État de l'art 3. Pourquoi l'utiliser ? 4. Swift Server dans la vraie vie 5. Évolutions 15
  16. 16. 1. Les origines 16
  17. 17. 17
  18. 18. 18
  19. 19. Pourquoi Open Source ? 19
  20. 20. 20
  21. 21. 21
  22. 22. 22
  23. 23. 23
  24. 24. 24
  25. 25. 2. État de l'art 25
  26. 26. Swi! 3.1    26
  27. 27. 1.027
  28. 28. 1.1 28
  29. 29. 1.229
  30. 30. 2.030
  31. 31. 2.131
  32. 32. 2.232
  33. 33. 2.333
  34. 34. 3.034
  35. 35. Swi! 3.1 35
  36. 36. En 2015-16 1 versiontous les 2 mois 36
  37. 37. Un langage(presque) finalisé 37
  38. 38. Un langage complet 38
  39. 39. 39
  40. 40. 40
  41. 41. 41
  42. 42. 42
  43. 43. 43
  44. 44.    bibliothèques tierces    44
  45. 45. Beaucoup de bibliothèques tierces stables 45
  46. 46. 46
  47. 47. 47
  48. 48. 48
  49. 49. Bibliothèques C 49
  50. 50. Frameworks Web50
  51. 51. 51
  52. 52. 52
  53. 53. 53
  54. 54. 54
  55. 55. 55
  56. 56. Swi! Package Manager 56
  57. 57. SPM swift package init swift package fetch swift package update swift package generate-xcodeproj 57
  58. 58. Swi! Package Catalog 58
  59. 59. 59
  60. 60. 60
  61. 61. 61
  62. 62. Quelques images Docker — swiftdocker/swift/ — ibmcom/kitura-ubuntu/ — zewo/todobackend/ 62
  63. 63. Qualité du code63
  64. 64. 64
  65. 65. 65
  66. 66. 66
  67. 67. 67
  68. 68. Metriques de qualitéPour en savoir plus... speakerdeck.com/viteinfinite/be-the-quality-you-want- to-see-in-your-app-swift-edition 68
  69. 69. 69
  70. 70. 70
  71. 71. nuclide.io/docs/languages/swift/ 71
  72. 72. ! 72
  73. 73.           Enfin...           73
  74. 74. 3. Pourquoi l'utiliser ? 74
  75. 75. Développement actif75
  76. 76. 76
  77. 77. 77
  78. 78. 78
  79. 79. 79
  80. 80. 80
  81. 81. 81
  82. 82. Performance 82
  83. 83. Performance 83
  84. 84. Performance 84
  85. 85. Mémoire Source: http://benchmarksgame.alioth.debian.org 85
  86. 86. Applications isomorphes 86
  87. 87. GCD 87
  88. 88. 4. Dans la vraie vie 88
  89. 89. 89
  90. 90. 90
  91. 91. L'application Serveur 1. Routing 2. Fichiers statiques 3. Proxy YouTube 4. Caching 91
  92. 92. Package.swi! import PackageDescription let package = Package( name: "XebiaTV", dependencies: [ .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 5), .Package(url: "https://github.com/vapor/redis-provider.git", majorVersion: 1) ] ) 92
  93. 93. Router import Foundation import Vapor let drop = Droplet() let categoryController = CategoryController() let youtubeController = YouTubeController() drop.get("/categories", handler: categoryController.categories) drop.get("/playlistItems", handler: youtubeController.playlistItems) drop.get("/search", handler: youtubeController.search) drop.get("/live", handler: youtubeController.live) drop.get("/video", String.self, handler: youtubeController.video) drop.run() 93
  94. 94. Fichiers statiques import Foundation import Vapor import Core import HTTP final class CategoryController { private let dataLoader = DataFile() func categories(_ req: Request) throws -> ResponseRepresentable { let fileBody = try dataLoader.load(path: drop.workDir + "Data/categories.json") return Response(body: .data(fileBody)) } } 94
  95. 95. Proxy YouTube public final class YouTubeController { // ... func search(_ req: Request) throws -> ResponseRepresentable { let query = "(googleApisBaseUrl)/search?key=(apiKey)&channelId=(channelId)" return try drop.client.get(query) } } 95
  96. 96. // ... public func video(_ req: Request, videoId: String) throws -> ResponseRepresentable { let cacheKey = "video-(videoId)" guard let cached = try cacheService.load(for: cacheKey) else { let urls = try videoUrls(for: videoId) try cacheService.save(node: urls, with: cacheKey, expiration: cacheExpiration) return try JSON(node: urls) } return try JSON(node: cached) } private func videoUrls(for videoId: String) throws -> Node { guard let urls = try LiveStreamerReader.read(videoId: videoId) else { throw Error.noVideo } return Node(["urls": Node.array(urls)]) } 96
  97. 97. Intégration avec LiveStreamer static func launch(_ command: String, args: [String] = []) throws -> Data { #if os(Linux) let task = Task() #else let task = Process() #endif let pipe = Pipe() task.launchPath = command task.arguments = args task.standardOutput = pipe task.launch() let data = pipe.fileHandleForReading.readDataToEndOfFile() task.waitUntilExit() return data } 97
  98. 98. Cache avec Redis public protocol CacheService { func load(for key: String) throws -> Node? func save(node: Node, with key: String, expiration: TimeInterval) throws } public class RedisService : CacheService { private let drop: Droplet public init(drop: Droplet) throws { try drop.addProvider(VaporRedis.Provider(config: drop.config)) self.drop = drop } public func load(for key: String) throws -> Node? { return try drop.cache.get(key) } public func save(node: Node, with key: String, expiration: TimeInterval) throws { try drop.cache.set(key, node) if let redisCache = drop.cache as? RedisCache { try redisCache.redbird.command("EXPIRE", params: [key, "(Int(expiration))"]) } } } 98
  99. 99. Build $ swift build Compile CLibreSSL xts128.c Compile CLibreSSL x_x509a.c Compile CLibreSSL xcbc_enc.c Compile CLibreSSL x_spki.c .... Compile Swift Module 'libc' (1 sources) Compile Swift Module 'SocksCore' (15 sources) Compile Swift Module 'Jay' (21 sources) Linking CLibreSSL Compile Swift Module 'Core' (28 sources) Compile Swift Module 'Routing' (11 sources) Compile Swift Module 'HTTPRouting' (5 sources) Compile Swift Module 'TypeSafeRouting' (3 sources) Compile Swift Module 'Cache' (3 sources) Compile Swift Module 'Auth' (15 sources) Compile Swift Module 'Vapor' (92 sources) Compile Swift Module 'VaporRedis' (2 sources) Compile Swift Module 'App' (6 sources) 99
  100. 100. Tests class AppTests: XCTestCase { // ... Create a StubCategoryController func testCategoryRoute() throws { let drop = try makeTestDroplet(categoryController: StubCategoryController()) let request = try Request(method: .get, uri: "/categories") let response = try drop.respond(to: request) let jsonBody = try JSON(bytes: response.body.bytes!) XCTAssertEqual(jsonBody["categories"]?.string, "someCategory") } } 100
  101. 101. 101
  102. 102.     Tout s'est bien passé™ 102
  103. 103.           Enfin...           103
  104. 104. 104
  105. 105. 105
  106. 106. Cross platform #if os(Linux) import Glibc #else import Darwin #endif 106
  107. 107. Swift Build 107
  108. 108. Swi! Package Manager Mess swift package generate-xcodeproj 108
  109. 109. Tester c'est linker (?) Undefined symbols for architecture x86_64: "test2.test2.init () -> test2.test2", referenced from: test2Tests.test2Tests.(testExample () -> ()). (implicit closure #1) in test2Tests.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 109
  110. 110. 5. Évolutions 110
  111. 111. Encore plus de Frameworks 111
  112. 112. Encore plus de APIs Swi! 112
  113. 113. 113
  114. 114. 114
  115. 115. Peut-on le déployer en prod ? 115
  116. 116. Oui ! 116
  117. 117.           Enfin...           117
  118. 118. Merci ! 118
  119. 119. Simone Cive!a119
  120. 120. Je suis un développeur iOS 120
  121. 121. Je suis un développeur Back 121
  122. 122.           Enfin...           122
  123. 123. 123
  124. 124. Be a Be!er Developer beabe!er.ninja 124
  125. 125. 125

×