# # #
##
Server-side Swift
&
Photo Booth
1. Swift Server with Kitura
なぜSwiftでServer開発か
• Swiftの型安全性がじわじわ効いてきて開発が楽
• Frameworkも色々でていて、導入が楽
• 後々iOS開発にも活かせそう
• 単にSwiftが好き
開発手順 (IBM Kituraで
)
$ swift package init ̶type executable
Edit package.swift to add dependencies
dependencies: [
.package(url: "https://github.com/IBM-Swift/Kitura", from: "2.4.0")
],
targets: [
.target(
name: "KituraServer",
dependencies: ["Kitura"])
]
$ swift package update
$ swift package generate-xcodeproj
main.swift
import Kitura
let router = Router()
.all("") { (req, res, next) in
res.send("Good")
}
Kitura.addHTTPServer(onPort: 8080, with: router)
Kitura.run()
Kituraの便利な機能
• Middleware
• RedirectionやJSON Parsingなど
• Codable Routing
• JSONを自動的にParseしてTypeに変換してくれる
HTTPS hosting
• LINE Messaging APIなどに必要
• The Messaging API allows for data to be passed between the server of your bot
application and the LINE Platform.
• 一時的な解決方法としてはngrokがとても便利
• ngrok exposes local servers behind NATs and firewalls to the public internet over
secure tunnels.
• Dockerを使ってHerokuにdeployする手もあるので紹介
• buildpackという手もあるけど、codeを直接公開しないで設置したかったので
• Heroku lets you deploy, run and manage applications written in Ruby, Node.js, Java,
Python, Clojure, Scala, Go and PHP.
• Docker: software containerization platform
https://developers.line.me/en/docs/messaging-api/overview/
https://ngrok.com/product
https://devcenter.heroku.com/articles/how-heroku-works
https://www.docker.com/what-docker
HerokuでDocker利用の流れ
事前準備
1. dockerとHeroku-CLIをインストールする
2. Herokuアカウントを作っておく
Create your app if not yet
/yourProject $ heroku login
/yourProject $ heroku create
・Dockerfile と docker-copmose.yml を作成する
Push your container
/yourProject $ heroku container:login
/yourProject $ heroku container:push web
/yourProject $ heroku container:release web
Dockerfile
• Dockerfile: imageをビルドするために必要なコマンドを
全て含んだtextファイル
# Base image from https://github.com/IBM-Swift/swift-ubuntu-docker
FROM ibmcom/swift-ubuntu:4.1.2
# Set environment variables for image
ARG PORT
ENV PORT ${PORT}
# Project Folder
ADD ./ /app
WORKDIR /app
RUN swift build --product <Project Target’s name> -c release
RUN chmod -R a+w /app && chmod 755 /app
CMD swift run <Project Target’s name> -c release
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
Dockerfile
docker-compose.yml
• docker-compose.yml: 環境変数やPortなどを設定する
textファイル
version: '2'
services:
web:
build: .
command: "bash -c 'swift run <Project Target’s name> -c release'"
working_dir: /app/
environment:
PORT: 8000
ports:
- '${PORT}:8000'
docker-compose.yml
For local test
/yourProject $ export $PORT=8080
/yourProject $ docker-copmose run ̶service-ports web
https://docs.docker.com/compose/reference/overview/
https://devcenter.heroku.com/articles/local-development-with-docker-compose
苦労など
• Ubuntu用のバイナリしか配布されていない
• 他の環境ではBuildするところからなので一手間
• iOSで使える関数が未実装なことがある
• 少しずつ実装進行中… 最新情報は右下の参考URLで
• MacとLinuxで使えるライブラリが違うことがある
• 例: RSA利用時のSecurity FrameworkとOpenSSL
• Linux用にはDocker内でswift buildして開発することは可能
https://swift.org/download/#releases
https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Status.md
2. Photo Booth and Swift
先週13日に運用開始
デモ動画
システム構成(6/13版)
Local Network
socket.io
socket.io
Bonjour
Bonjour
Web server
Web server
Swift
Swift
Swift
Swift
Swift
Swift
socket.io
• Global networkで受け取った情報をLocal network内に
転送するために利用
• header含めrequest bodyを丸ごと転送
• Global側はnode.jsで実装(作業分担したので)
• 部外者からのEventは署名を検証することで排除
• Swiftで動作させるのはとても簡単 (なので詳細省略)
• ただ支障ない程度に切断/再接続が繰り返される(原因不明)
https://github.com/socketio/socket.io-client-swift
Bonjour (NetService)
• aka zero-configuration networking
• WiTapというAppleの公式サンプルを参考に実装
• streamのbuffer sizeがあまり大きくない
• 10KBくらいまでは安定
• main thread以外で走らせると
delegate methodが受け取れない(原因不明)
https://developer.apple.com/bonjour/
https://developer.apple.com/library/archive/samplecode/WiTap/Introduction/Intro.html
NetService 利用の流れ
1. NetService インスタンスを生成して自身をPublish
2. RunLoop内で他のServiceを検索
3. I/O Streamを開く / 接続を受け入れる
4. I/O Streamを使って読み書き
Web server with Kitura
• Kituraを任意のThreadで実行する
• Pathからパラメータを受け取って任意のコマンドを実行
DispatchQueue.init(label: "Kitura").async {
Kitura.addHTTPServer(onPort: port, with: router)
Kitura.run()
RunLoop.current.run()
}
router.delete("photo/:hashString") { (req, res, next) in
if let photo = (images.filter { $0.hashString ==
req.parameters["hashString"] }.first) {
delete(photo: photo)
}
}
リファクタリング
• 現行の方式は柔軟性は高いが、
Context Server周りの設定内容が多い
• Bonjourのdomainやnameなどを一致させて
かつ重複を避ける必要性
• Admin toolのためにLocal IPを調べる必要性
• Context Serverを走らせるためにPCが1台必要
• iPhone appに移動できるコードを移動してしまえば?
リファクタ後(6/22版)
Swift Server??
socket.io
socket.io
ご静聴ありがとうございました

Server side Swift & Photo Booth