Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Swi!
Côté Serveur
1
Salut
2
Simone
Cive!a3
Je suis
un développeur
iOS 4
7ans
5
6
4ans
7
8
9
10
11
12
13
 
        Enfin...        
 
14
Plan1. Les Origines
2. État de l'art
3. Pourquoi l'utiliser ?
4. Swift Server dans la vraie vie
5. Évolutions
15
1. Les origines
16
17
18
Pourquoi Open Source ?
19
20
21
22
23
24
2. État de l'art
25
Swi! 3.1   
26
1.027
1.1 28
1.229
2.030
2.131
2.232
2.333
3.034
Swi! 3.1
35
En 2015-16
1 versiontous les
2 mois 36
Un langage(presque)
finalisé
37
Un langage
complet
38
39
40
41
42
43
  
bibliothèques
tierces
  
44
Beaucoup de
bibliothèques
tierces
stables 45
46
47
48
Bibliothèques C
49
Frameworks
Web50
51
52
53
54
55
Swi!
Package
Manager
56
SPM
swift package init
swift package fetch
swift package update
swift package generate-xcodeproj
57
Swi! Package Catalog
58
59
60
61
Quelques images Docker
— swiftdocker/swift/
— ibmcom/kitura-ubuntu/
— zewo/todobackend/
62
Qualité
du code63
64
65
66
67
Metriques de qualitéPour en savoir plus...
speakerdeck.com/viteinfinite/be-the-quality-you-want-
to-see-in-your-app-swift-e...
69
70
nuclide.io/docs/languages/swift/
71
! 72
 
        Enfin...        
 
73
3. Pourquoi
l'utiliser ?
74
Développement
actif75
76
77
78
79
80
81
Performance
82
Performance
83
Performance
84
Mémoire
Source: http://benchmarksgame.alioth.debian.org
85
Applications
isomorphes
86
GCD
87
4. Dans la vraie vie
88
89
90
L'application Serveur
1. Routing
2. Fichiers statiques
3. Proxy YouTube
4. Caching
91
Package.swi!
import PackageDescription
let package = Package(
name: "XebiaTV",
dependencies: [
.Package(url: "https://gith...
Router
import Foundation
import Vapor
let drop = Droplet()
let categoryController = CategoryController()
let youtubeContro...
Fichiers statiques
import Foundation
import Vapor
import Core
import HTTP
final class CategoryController {
private let dat...
Proxy YouTube
public final class YouTubeController {
// ...
func search(_ req: Request) throws -> ResponseRepresentable {
...
// ...
public func video(_ req: Request, videoId: String) throws -> ResponseRepresentable {
let cacheKey = "video-(videoId...
Intégration avec LiveStreamer
static func launch(_ command: String, args: [String] = []) throws -> Data {
#if os(Linux)
le...
Cache avec Redis
public protocol CacheService {
func load(for key: String) throws -> Node?
func save(node: Node, with key:...
Build
$ swift build
Compile CLibreSSL xts128.c
Compile CLibreSSL x_x509a.c
Compile CLibreSSL xcbc_enc.c
Compile CLibreSSL ...
Tests
class AppTests: XCTestCase {
// ... Create a StubCategoryController
func testCategoryRoute() throws {
let drop = try...
101
 
 
Tout s'est bien passé™
102
 
        Enfin...        
 
103
104
105
Cross platform
#if os(Linux)
import Glibc
#else
import Darwin
#endif
106
Swift Build
107
Swi! Package Manager Mess
swift package generate-xcodeproj
108
Tester c'est linker (?)
Undefined symbols for architecture x86_64:
"test2.test2.init () -> test2.test2", referenced from:
...
5. Évolutions
110
Encore plus de
Frameworks
111
Encore plus de
APIs Swi!
112
113
114
Peut-on
le déployer
en prod ?
115
Oui !
116
 
        Enfin...        
 
117
Merci !
118
Simone
Cive!a119
Je suis
un développeur
iOS 120
Je suis
un développeur
Back 121
 
        Enfin...        
 
122
123
Be a
Be!er
Developer
beabe!er.ninja
124
125
Upcoming SlideShare
Loading in …5
×

Devoxx 17 - Swift server-side

467 views

Published on

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.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

×