Slide 1

Slide 1 text

Server-Side Swift as a Live Example @tnantokaɹɹɹɹɹɹɹɹɹɹɹ

Slide 2

Slide 2 text

Server-Side Swift?

Slide 3

Slide 3 text

Yes!

Slide 4

Slide 4 text

Why?

Slide 5

Slide 5 text

"Because it's there."

Slide 6

Slide 6 text

No...

Slide 7

Slide 7 text

Why?

Slide 8

Slide 8 text

"No reason."

Slide 9

Slide 9 text

We Can Use → Rails → Go → Node → Scala ...

Slide 10

Slide 10 text

Why?

Slide 11

Slide 11 text

ns*.com → nsdateformatter.com → nsregularexpression.com

Slide 12

Slide 12 text

Server-Side Swift as a Live Example

Slide 13

Slide 13 text

Showcase

Slide 14

Slide 14 text

nsurl.serversideswift.net

Slide 15

Slide 15 text

stringfilter.herokuapp.com

Slide 16

Slide 16 text

sssaale-reversi.herokuapp.com

Slide 17

Slide 17 text

How to Make

Slide 18

Slide 18 text

Framework ⭐ Perfect 10700+ Vapor 8800+ Kitura 5300+

Slide 19

Slide 19 text

Environment → Xcode (auto-completion) → swiftdocker/docker-swift (Linux)

Slide 20

Slide 20 text

#if os(Linux) error: use of unresolved identifier 'NSRegularExpression' error: value of type 'NSURL' has no member 'isFileReferenceURL' error: cannot convert value of type 'NSMutableString' to expected argument type 'CFMutableString!' (›°□°)›ớᵲᴸᵲ

Slide 21

Slide 21 text

Hello, World!

Slide 22

Slide 22 text

sssaale.herokuapp.com

Slide 23

Slide 23 text

AppLogic/Droplet+Setup.swift // GET / -> Views/welcome.leaf drop.get { req in return try drop.view.make("welcome", [ "title": title ]) } // /example -> Controllers/ExampleController.swift drop.resource("example", ExampleController())

Slide 24

Slide 24 text

Models/Example.swift final class Example: Model { // Input -> Output var input: String var output: String { return input.uppercased() } // JSON -> Model init(node: Node, in context: Context) throws { input = try node.extract("input") } // Model -> JSON func makeNode(context: Context) throws -> Node { return try Node(node: [ "output": output, ]) } }

Slide 25

Slide 25 text

Controllers/ExampleController.swift final class ExampleController: ResourceRepresentable { // Model -> JSON func create(request: Request) throws -> ResponseRepresentable { let example = try request.example() return example } // POST /example -> create func makeResource() -> Resource { return Resource( store: create ) } }

Slide 26

Slide 26 text

AppLogicTests/AppLogicTests.swift func testExample() { let drop = try! makeTestDroplet() let json = try! JSON(node: .object([ "input" : "hello" ])) let req = try! Request( method: .post, uri: "/example", headers: [ HeaderKey.contentType : "application/json" ], body: json.makeBody() ) let res = try! drop.respond(to: req) let body = res.body.bytes!.string XCTAssertTrue(body.contains("HELLO")) // hello -> HELLO }

Slide 27

Slide 27 text

Live Coding

Slide 28

Slide 28 text

Create Project $ vapor new MarkdownEditor --template=tnantoka/sssaale $ cd MarkdownEditor $ vapor xcode -y

Slide 29

Slide 29 text

Package.swift + .Package( + url: "https://github.com/IBM-Swift/Kitura-Markdown.git", + majorVersion: 0, + minor: 8 + ),

Slide 30

Slide 30 text

Models/Example.swift + import KituraMarkdown - return input.uppercased() + return KituraMarkdown.render(from: input)

Slide 31

Slide 31 text

scripts/app.js -

Slide 32

Slide 32 text

AppLogicTests/AppLogicTests.swift - try! JSON(node: .object([ "input" : "hello" ])) + try! JSON(node: .object([ "input" : "# hello" ])) - XCTAssertTrue(body.contains("HELLO")) + XCTAssertTrue(body.contains("

hello

"))

Slide 33

Slide 33 text

Test & Run $ docker pull swiftdocker/swift $ docker run -it -v `pwd`:/app -w /app -p 8080:8080 swiftdocker/swift $ swift test $ .build/Debug/App

Slide 34

Slide 34 text

localhost:8080

Slide 35

Slide 35 text

Deploy $ vapor heroku init $ vapor heroku push

Slide 36

Slide 36 text

sssaale-markdown.herokuapp.com

Slide 37

Slide 37 text

try! Server-Side Swift