the joy of server side swift development
TRANSCRIPT
![Page 1: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/1.jpg)
The Joy Of Server Side Swift Development
![Page 2: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/2.jpg)
In 1943 Konrad Zuse invented Plankalkül
![Page 3: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/3.jpg)
1940s
9 Programming languages
![Page 4: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/4.jpg)
1950s
... - Fortran(concept) - Fortran II - ALGOL 58(IAL) - LISP(implementation) ...
![Page 5: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/5.jpg)
1950s
58 Programming languages
![Page 6: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/6.jpg)
1960s
...- ALGOL 60 - COBOL 61(implementation) - FORTRAN IV - APL(concept) - Simula(concept) - SNOBOL - CPL - SNOBOL3 - ALGOL 68(concept) - BASIC ...
![Page 7: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/7.jpg)
1960s
113 Programming languages
![Page 8: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/8.jpg)
1970s
... - Pascal - Smalltalk - C - Prolog - Structured Query language ( SQL) - Bourne Shell(sh) - Modula-2 - AWK...
![Page 9: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/9.jpg)
1970s
170 Programming languages
![Page 10: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/10.jpg)
1980s
... - Ada 80(MIL-STD-1815) - GW-BASIC - Turbo Pascal - Objective-C - C++ - Eiffel - Erlang...
![Page 11: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/11.jpg)
1980s
231 Programming languages
![Page 12: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/12.jpg)
1990s
... - AMOS BASIC - Haskell - Python - Visual Basic - Brainfuck - Borland Delphi - Java - PHP - Ruby - JavaScript - Standard C++...
![Page 13: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/13.jpg)
1990s
292 Programming languages
![Page 14: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/14.jpg)
2000s
...- ActionScript- C#- D- Scala- Groovy- F#- Clojure- Go...
![Page 15: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/15.jpg)
2000s
339 Programming languages
![Page 16: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/16.jpg)
2010s
... - Rust - Elm - Kotlin - Elixir - Hack - C++14 ...
![Page 17: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/17.jpg)
2010s
354 Programming languages
![Page 18: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/18.jpg)
and then...
![Page 19: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/19.jpg)
![Page 20: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/20.jpg)
355
![Page 21: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/21.jpg)
Do we really need another programming language?
![Page 22: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/22.jpg)
Who Am I?@giordanoscalzohttps://github.com/gscalzo
A developer
![Page 23: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/23.jpg)
![Page 24: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/24.jpg)
![Page 25: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/25.jpg)
![Page 26: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/26.jpg)
![Page 27: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/27.jpg)
![Page 28: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/28.jpg)
After one year
![Page 29: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/29.jpg)
![Page 30: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/30.jpg)
![Page 31: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/31.jpg)
For Real!
![Page 32: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/32.jpg)
![Page 33: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/33.jpg)
![Page 34: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/34.jpg)
![Page 35: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/35.jpg)
Officially, only Linux is Supported
![Page 36: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/36.jpg)
Being Open-Source...
![Page 37: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/37.jpg)
![Page 38: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/38.jpg)
![Page 39: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/39.jpg)
![Page 40: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/40.jpg)
Server side development without a web framework?
![Page 41: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/41.jpg)
We have a few...
![Page 42: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/42.jpg)
Perfect: github.github.com/PerfectlySoft/Perfect (8829) Vapor: github.com/vapor/vapor (6763) Kitura: github.com/IBM-Swift/Kitura (4578) Swifton: github.com/necolt/Swifton (2016) Zewo: github.com/Zewo/Zewo (1358) Blackfish: github.com/elliottminns/blackfish (932) Slimane: github.com/noppoMan/Slimane (61) Tailor: github.com/brownleej/tailor (55) Kunugi: github.com/novi/Kunugi (35) Quark: github.com/QuarkX/Quark (33)
![Page 43: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/43.jpg)
![Page 44: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/44.jpg)
"Perfect is a complete and powerful toolbox,
framework, and application server for Linux, iOS, and
macOS"
![Page 45: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/45.jpg)
They got money(Even without React. js!)
![Page 46: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/46.jpg)
![Page 47: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/47.jpg)
Open-source-ish, but enterprise-ish...
![Page 48: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/48.jpg)
![Page 49: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/49.jpg)
Sean StephensChief Executive Officer
![Page 50: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/50.jpg)
let server = HTTPServer()
var routes = Routes()routes.add(method: .get, uri: "/", handler: { request, response in response.setHeader(.contentType, value: "text/html") response.appendBody(string: "<html><title>Hello, world!</title><body>Hello, world!</body></html>") response.completed() })
server.addRoutes(routes)server.serverPort = 8181server.documentRoot = "./webroot"configureServer(server)
do { try server.start()} catch PerfectError.networkError(let err, let msg) { print("Network error thrown: \(err) \(msg)")}
![Page 51: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/51.jpg)
![Page 52: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/52.jpg)
4 Laravel inspired
4 Easy to setup
4 Fantastic Command Line Tool
![Page 53: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/53.jpg)
![Page 54: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/54.jpg)
let drop = Droplet()drop.get("/") { request in return try drop.view.make("welcome.html")}drop.get("plaintext") { request in return "Hello, World!"}drop.serve()
![Page 55: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/55.jpg)
![Page 56: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/56.jpg)
![Page 57: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/57.jpg)
4 Backed by IBM
4 Express.js-like
4 Perfectly integrated in IBM cloud solution BlueMix
![Page 58: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/58.jpg)
![Page 59: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/59.jpg)
import Kitura
let router = Router()
router.get("/") { request, response, next in response.send("Hello, World!") next()}
Kitura.addHTTPServer(onPort: 8080, with: router)Kitura.run()
![Page 60: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/60.jpg)
Let's talk now of...
![Page 61: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/61.jpg)
Performance!
![Page 62: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/62.jpg)
Benchmarks are difficult
![Page 63: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/63.jpg)
![Page 64: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/64.jpg)
and useless...
![Page 65: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/65.jpg)
![Page 66: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/66.jpg)
![Page 67: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/67.jpg)
![Page 68: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/68.jpg)
![Page 69: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/69.jpg)
![Page 70: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/70.jpg)
Swift Frameworks Benchmarks
![Page 71: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/71.jpg)
![Page 72: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/72.jpg)
Fair Enough
![Page 73: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/73.jpg)
Let's do some code
![Page 74: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/74.jpg)
You can write Basic in Swift...
![Page 75: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/75.jpg)
You can write Haskell-ish in Swift...
![Page 76: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/76.jpg)
The sense of Swift
![Page 77: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/77.jpg)
An Isomorphic Swift App!
![Page 78: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/78.jpg)
A Universal Swift App!
![Page 79: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/79.jpg)
![Page 80: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/80.jpg)
![Page 81: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/81.jpg)
Introducing
Mr Drizzle!
![Page 82: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/82.jpg)
An hyper local weather app
![Page 83: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/83.jpg)
![Page 84: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/84.jpg)
![Page 85: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/85.jpg)
![Page 86: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/86.jpg)
![Page 87: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/87.jpg)
MrDrizzle Server Requirements:4 Convert from Wunderground Models to MrDrizzle
Model
4 Refresh cache every hour
![Page 88: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/88.jpg)
MrDrizzle Server
![Page 89: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/89.jpg)
![Page 90: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/90.jpg)
mkdir MrDrizzleServercd MrDrizzleServerswift package init --type executable
![Page 91: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/91.jpg)
![Page 92: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/92.jpg)
Swift Package Managerimport PackageDescription
let package = Package( name: "MrDrizzleServer", dependencies: [ .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 0) ])
![Page 93: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/93.jpg)
Let's make it run
// main.swiftimport Foundationimport HTTPimport Vapor
let wheaterUndergroundKey = "KEY"let wheaterUndergroundDomain = "api.wunderground.com"
let drop = Droplet()
drop.get("/hello") { _ in return "Hello World"}
drop.run()
![Page 94: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/94.jpg)
$ swift build
> Cloning https://github.com/vapor/vapor.git> HEAD is now at 453f7cf Merge pull request #628> Resolved version: 1.0.3> Cloning https://github.com/vapor/crypto.git> HEAD is now at 0aaa68b Merge pull request #15> Resolved version: 1.0.1> Cloning https://github.com/vapor/core.git........> Compile Swift Module 'TypeSafeRouting' (3 sources)> Compile Swift Module 'Vapor' (83 sources)> Compile Swift Module 'MrDrizzleServer' (1 sources)> Linking ./.build/debug/MrDrizzleServer
$ .build/debug/MrDrizzleServer
![Page 95: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/95.jpg)
> Could not load localization files> No cipher key was set, using blank key.> Chacha20 cipher requires an initialization > No command supplied, defaulting to serve> No preparations.> No servers.json configuration found.> Starting server at 0.0.0.0:8080
![Page 96: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/96.jpg)
![Page 97: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/97.jpg)
![Page 98: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/98.jpg)
$ swift package generate-xcodeproj> generated: ./MrDrizzleServer.xcodeproj
![Page 99: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/99.jpg)
![Page 100: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/100.jpg)
Hello World for dummies
![Page 101: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/101.jpg)
This version:
drop.get("/hello") { _ in return "Hello World"}
![Page 102: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/102.jpg)
Is equivalent to:
func handler(request: Request) throws -> ResponseRepresentable { return Response(status: .ok, body: "Hello, World")}drop.get("/hello", handler: handler)
because:
extension Swift.String: ResponseRepresentable { public func makeResponse() -> Response { return Response(body: self.bytes) }}
![Page 103: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/103.jpg)
Go back to MrDrizzleServer
![Page 104: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/104.jpg)
The list of the stations:
struct StationInfo { let name: String let stationId: String let lat: Float let lon: Float}
let stationsInfo = [ StationInfo(name: "Chelsea", stationId: "ILONDON330", lat: 51.479633, lon:-0.180277), StationInfo(name: "Westminster", stationId: "ILONDON120", lat: 51.65343, lon:-0.183732) //...]
![Page 105: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/105.jpg)
Let's define a schema for our models
![Page 106: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/106.jpg)
Model schema in pseudocode
object Stations { Array of Station stations }object Station { string id float lat float lon string name Array of HourlyMeasure measures}object HourlyMeasure { int32 hour float temp_f float temp_c}
![Page 107: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/107.jpg)
syntax = "proto3";
message Stations { repeated Station stations = 1;}message Station { string id = 1; float lat = 2; float lon = 3; string name = 4; repeated HourlyMeasure measures = 5;}message HourlyMeasure { int32 hour = 1; float temp_f = 2; float temp_c = 3;}
![Page 108: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/108.jpg)
protobuf
Invented by Apple
![Page 109: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/109.jpg)
![Page 110: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/110.jpg)
Given this:
syntax = "proto3";
message Stations { repeated Station stations = 1;}message Station { string id = 1; float lat = 2; float lon = 3; string name = 4; repeated HourlyMeasure measures = 5;}message HourlyMeasure { int32 hour = 1; float temp_f = 2; float temp_c = 3;}
![Page 111: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/111.jpg)
/* * DO NOT EDIT. * * Generated by the protocol buffer compiler. * Source: mrdrizzle.proto * */
public struct Stations: ProtobufGeneratedMessage { public var swiftClassName: String {return "Stations"} public var protoMessageName: String {return "Stations"} public var protoPackageName: String {return ""} //...}
public struct Station: ProtobufGeneratedMessage { public var swiftClassName: String {return "Station"} public var protoMessageName: String {return "Station"} public var protoPackageName: String {return ""} //...}
public struct HourlyMeasure: ProtobufGeneratedMessage { public var swiftClassName: String {return "HourlyMeasure"} public var protoMessageName: String {return "HourlyMeasure"} public var protoPackageName: String {return ""}
//...}
![Page 112: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/112.jpg)
We extend these structs to instantiate from the wunderground JSON
![Page 113: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/113.jpg)
Wheater Underground JSON:
{ "response": { "version": "0.1", }, "hourly_forecast": [ { "FCTTIME": { "hour": "22", "mday": "19", "mday_padded": "19", "yday": "292", "isdst": "1", "age": "", "UTCDATE": "" }, "temp": { "english": "52", "metric": "11" }, "condition": "Clear", "icon": "clear", "metric": "-9999" }, ...
![Page 114: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/114.jpg)
extension Station { init?(stationInfo: StationInfo, json: JSON) { guard let hourly_forecast = json["hourly_forecast"]?.array as? [JSON] else { return nil }
let measures = hourly_forecast.flatMap { HourlyMeasure(json: $0) }
self.init(lat: stationInfo.lat, lon: stationInfo.lon, name: stationInfo.name, measures: measures) }}
![Page 115: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/115.jpg)
extension HourlyMeasure { init?(json: JSON) { guard let fctTime = json["FCTTIME"]?.object, let hour = fctTime["hour"]?.string, let temp = json["temp"]?.object, let tempF = temp["english"]?.string, let tempC = temp["metric"]?.string else { return nil }
self.init(hour: Int32(hour), tempF: Float(tempF), tempC: Float(tempC)) }}
![Page 116: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/116.jpg)
Retrieving from Wunderground Server
![Page 117: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/117.jpg)
extension Station { init?(stationInfo: StationInfo, client: ClientProtocol.Type) { let url = "http://\(wheaterUndergroundDomain)/api/" + "\(wheaterUndergroundKey)/hourly/q/pws:" + "\(stationInfo.stationId).json" guard let response = try? client.get(url), case .data(let bytes) = response.body, let json = try? JSON(bytes: bytes) else { return nil }
self.init(stationInfo: stationInfo, json: json) } }
![Page 118: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/118.jpg)
Refreshing every hour
![Page 119: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/119.jpg)
We cannot use URLSession :-(class WeatherService { private let refreshQueue = DispatchQueue(label: "com.mrdrizzle.refresh") private(set) var stations = Stations()
init(stationsInfo: [StationInfo], client: ClientProtocol.Type) { refresh(stationsInfo: stationsInfo, client: client) }
private func refresh(stationsInfo: [StationInfo], client: ClientProtocol.Type) { stations = stations.refreshed(given: stationsInfo, client: client) refreshQueue.asyncAfter(deadline: .now() + 3600) { [weak self] in self?.refresh(stationsInfo: stationsInfo, client: client) } } }
![Page 120: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/120.jpg)
private extension Stations { func refreshed(given stationsInfo: [StationInfo], client: ClientProtocol.Type) -> Stations { return Stations(stations: stationsInfo.flatMap { Station(stationInfo: $0, client: client) }) }}
![Page 121: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/121.jpg)
Putting everything together
![Page 122: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/122.jpg)
//main.swiftlet drop = Droplet()
let stationsInfo = [ StationInfo(name: "Chelsea", stationId: "ILONDON330", lat: 51.479633, lon:-0.180277), StationInfo(name: "Westminster", stationId: "ILONDON120", lat: 51.65343, lon:-0.183732) //...]
let weatherService = WeatherService(stationsInfo: stationsInfo, client: drop.client)
drop.get("/api/weather") { _ in let stations = weatherService.stations
guard let data = try? stations.serializeProtobuf(), let bytes = try? data.makeBytes() else { throw Abort.serverError }
return Response(status: .ok, body: .data(bytes))}
drop.run()
![Page 123: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/123.jpg)
Job done!
![Page 124: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/124.jpg)
MrDrizzle Client
![Page 125: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/125.jpg)
Networking classes from
https://talk.objc.io/episodes/S01E01-
networking
![Page 126: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/126.jpg)
struct Resource<A> { let url: URL let parse: (Data) -> A?}
for example:
let url = URL(string: "http://mrdrizzle.com:8080/hello")!let helloResource = Resource<String>(url: url, parse: { data in return String(data: data, encoding: .utf8)})
![Page 127: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/127.jpg)
class ApiService { func load<A>(resource: Resource<A>, completion: @escaping (A?) -> ()) { URLSession.shared.dataTask(with: resource.url) { data, response, error in guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let data = data else { completion(nil) return }
completion(resource.parse(data)) }.resume() }}
![Page 128: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/128.jpg)
let url = URL(string: "http://mrdrizzle.com:8080/hello")!let helloResource = Resource<String>(url: url) { data in return String(data: data, encoding: .utf8)}
ApiService().load(resource: helloResource) { guard let hello = $0 else { print("ERROR - Hello") return }
print(hello)}
![Page 129: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/129.jpg)
let url = URL(string: "http://mrdrizzle.com:8080/hello")!let stationResources = Resource<Stations>(url: url) { data in return try? Stations(protobuf: data)}
ApiService().load(resource: stationResources) { guard let stations = $0 else { print("ERROR - Stations") return }
print(stations)}
![Page 130: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/130.jpg)
![Page 131: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/131.jpg)
It's ok :-)
![Page 132: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/132.jpg)
Recap
![Page 133: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/133.jpg)
![Page 134: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/134.jpg)
![Page 135: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/135.jpg)
However...
![Page 136: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/136.jpg)
Apps are so 2014!
![Page 137: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/137.jpg)
Let's do something modern
![Page 138: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/138.jpg)
A Deep Learning Functional Reactive Chatbot!
![Page 139: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/139.jpg)
Story behind it
![Page 140: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/140.jpg)
![Page 141: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/141.jpg)
![Page 142: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/142.jpg)
![Page 143: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/143.jpg)
![Page 144: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/144.jpg)
![Page 145: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/145.jpg)
![Page 146: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/146.jpg)
Diagram of a Facebook Messenger ChatBot
![Page 147: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/147.jpg)
![Page 148: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/148.jpg)
![Page 149: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/149.jpg)
Chat Flow
![Page 150: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/150.jpg)
![Page 151: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/151.jpg)
![Page 152: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/152.jpg)
![Page 153: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/153.jpg)
![Page 154: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/154.jpg)
Let's do it
![Page 155: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/155.jpg)
![Page 156: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/156.jpg)
import PackageDescription
let package = Package( name: "UncleLucio", dependencies: [ .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 0) ])
![Page 157: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/157.jpg)
// main.swiftimport Foundationimport Vaporimport HTTP
let PAGE_ACCESS_TOKEN = "STUFF"let fbURL = "https://graph.facebook.com/v2.6/me/messages?access_token=" + PAGE_ACCESS_TOKEN
let uncleLucio = UncleLucio(jokesDB: JokesDB())let drop = Droplet()
![Page 158: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/158.jpg)
// main.swiftdrop.get("fbwebhook") { request in guard let token = request.data["hub.verify_token"]?.string, let response = request.data["hub.challenge"]?.string else { throw Abort.badRequest }
if token == "UNCLELUCIO_VERIFICATION_TOKEN" { return response // Response(status: .ok, text: response) } else { return "Error, invalid token"//Response(status: .ok, text: "Error, invalid token") }}
![Page 159: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/159.jpg)
// main.swiftdrop.post("fbwebhook") { request in
request.log()
guard let jsonBody = request.json, let chatMessage = ChatMessage(message: jsonBody) else { throw Abort.badRequest }
let replyMessage = uncleLucio.message(after: chatMessage) return try drop.client.post(fbURL, headers: ["Content-Type": "application/json; charset=utf-8"], body: replyMessage.toJSON())}
drop.run()
![Page 160: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/160.jpg)
// ChatMessage.swiftimport Foundationimport Vaporimport HTTP
struct ChatMessage { let sender: String let recipient: String let text: String?}
![Page 161: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/161.jpg)
Payload send by Facebook callback
{ "object": "page", "entry": [ { "id": "1677732245875632", "time": 1476209402183, "messaging": [ { "sender": { "id": "1243544059050238" }, "recipient": { "id": "1677732245875632" }, "timestamp": 1476209402090, "message": { "mid": "mid.1476209402075:82aff934133d72d746", "seq": 17, "text": "Knock knock" } } ] } ]}
![Page 162: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/162.jpg)
// ChatMessage.swiftextension ChatMessage { init?(message: JSON) { guard let entry = message["entry"]?.array?.first as? JSON else { return nil }
guard let messaging = entry["messaging"]?.array?.first as? JSON else { return nil }
guard let senderWrapper = messaging["sender"]?.object, let sender = senderWrapper["id"]?.string else { return nil } self.sender = sender guard let recipientWrapper = messaging["recipient"]?.object, let recipient = recipientWrapper["id"]?.string else { return nil } self.recipient = recipient guard let message = messaging["message"]?.object else { return nil } self.text = message["text"]?.string }}
![Page 163: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/163.jpg)
// ChatMessage.swiftextension ChatMessage { func toJSON() throws -> JSON { return try JSON(node: [ "sender": try JSON(node: [ "id": sender ]), "recipient": try JSON(node: [ "id": recipient ]), "message": try JSON(node: [ "text": text ]), ]) }}
![Page 164: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/164.jpg)
![Page 165: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/165.jpg)
// UncleLucio.swiftclass UncleLucio { private let jokesDB: JokesDB private var sessions = [String: State]()
init(jokesDB: JokesDB) { self.jokesDB = jokesDB }
func message(after chatMessage: ChatMessage) -> ChatMessage { //... return replyMessage }}
![Page 166: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/166.jpg)
// UncleLucio.swift func message(after chatMessage: ChatMessage) -> ChatMessage { let state = sessions[chatMessage.sender] ?? StartState(joke: jokesDB.randomJoke())
let (text, newState) = state.nextState(when: chatMessage.text ?? "pota")
if newState is Done { sessions.removeValue(forKey: chatMessage.sender) } else { sessions[chatMessage.sender] = newState } let replyMessage = ChatMessage(sender: chatMessage.recipient, recipient: chatMessage.sender, text: text) return replyMessage }
![Page 167: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/167.jpg)
// UncleLucio.swift
protocol State { func nextState(when message: String) -> (String, State)}
![Page 168: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/168.jpg)
// UncleLucio.swift
struct StartState: State { let joke: Joke func nextState(when message: String) -> (String, State) { if message.lowercased().contains("joke") { return ("Knock Knock", WaitingForReplyState(joke: joke)) } return ("pota", self) }}
![Page 169: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/169.jpg)
struct WaitingForReplyState: State { let joke: Joke func nextState(when message: String) -> (String, State) { let text = message.lowercased() if text.contains("who's there") || text.contains("who is there") { return ("\(joke.subject)!", WaitingForSubjectReplyState(joke: joke)) } return ("pota", StartState(joke: joke)) }}
![Page 170: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/170.jpg)
struct WaitingForSubjectReplyState: State { let joke: Joke func nextState(when message: String) -> (String, State) { let text = message.lowercased() if text.contains("\(joke.subject.lowercased()) who") { return ("\(joke.punchline)\nahahah", Done()) } return ("pota", StartState(joke: joke)) }}
![Page 171: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/171.jpg)
struct Done: State { func nextState(when message: String) -> (String, State) { return ("pota", Done()) }}
![Page 172: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/172.jpg)
Really easy to test
![Page 173: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/173.jpg)
func testInStart_ReceivingGarbage_SaysSlogan_GoesStart() { let state = StartState(joke: joke())
let (text, nextState) = state.nextState(when: "foobar") XCTAssertEqual(text, "pota")
XCTAssertTrue(nextState is StartState) }
![Page 174: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/174.jpg)
func testWaitingForSubjectReply_ReceivingReply_SaysPunchline_GoesDone() { let state = WaitingForSubjectReplyState(joke: joke())
let (text, nextState) = state.nextState(when: "\(joke().subject) who") XCTAssertEqual(text, "\(joke().punchline)\nahahah") XCTAssertTrue(nextState is Done) }
![Page 175: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/175.jpg)
class JokesDB { private let jokes: [Joke] = [ ("Harry", "Harry up and let me in!"), ("Wanda", "Wanda hang out with me right now?"), ("Olive", "Olive you and I don’t care who knows it!"), ("Ho-ho", "You know, your Santa impression could use a little work."), ("Hanna", "...Hanna partridge in a pear tree!"), ("Mary and Abbey", "Mary Christmas and Abbey New Year!"), ("Irish", "Irish you a Merry Christmas!"), ("Yule log", "Yule log the door after you let me in, won’t you?"), ("Ya", "I’m excited to see you too!"), ("Sherlock", "Sherlock your door shut tight!"), ("Scold", "Scold outside—let me in!"), ("Robin", "Robin you! Hand over your cash!"), ("Needle", "Needle little help gettin’ in the door."), ("Nana", "Nana your business who’s there."), ("Luke", "Luke through the keyhole to see!"), ("Isabelle", "Isabelle working, or should I keep knocking?"), ].map { Joke(subject: $0.0, punchline: $0.1) }
func randomJoke() -> Joke { return jokes.randomItem() }}
![Page 176: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/176.jpg)
extension Array { func randomItem() -> Element { let index = Int(arc4random_uniform(UInt32(self.count))) return self[index] }}
![Page 177: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/177.jpg)
https://github.com/gscalzo/UncleLucio
![Page 178: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/178.jpg)
Finally...
![Page 179: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/179.jpg)
A reason for using Swift in Server...
![Page 180: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/180.jpg)
Often in our job...
![Page 181: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/181.jpg)
![Page 182: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/182.jpg)
![Page 183: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/183.jpg)
![Page 184: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/184.jpg)
But sometimes...
![Page 185: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/185.jpg)
![Page 186: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/186.jpg)
![Page 187: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/187.jpg)
![Page 188: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/188.jpg)
"Everything in Its Right Place" (cit.)
![Page 189: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/189.jpg)
![Page 190: The Joy of Server Side Swift Development](https://reader033.vdocuments.site/reader033/viewer/2022052606/589cfce21a28abcc258b7123/html5/thumbnails/190.jpg)
Thank You!