Swiftがオープンソース化され、Linuxでも動作するようになりました。私はSwiftでアプリ開発を普段行っていますが、これを機にサーバー側も書いていきたいと思いました。
そこで今回はSwift製のWebフレームワークであるVaporを使ってみたので、紹介しようと思います。
Vaporとは
公式URLはこちらです。 https://github.com/tannernelson/vapor
A Laravel/Lumen Inspired Web Framework for Swift that works on iOS, OS X, and Ubuntu.
と説明が書いています。PHPのWebフレームワークのLaravelに影響を受けたフレームワークのようです。
これを使って、JSONを返すAPIを作成しました。
前提知識
Swiftとサーバーサイドの開発の経験があれば大丈夫です。Herokuを使うので、Herokuのアカウントは作成しておきましょう。Herokuの使い方の説明はここでは省きます。
Swiftのダウンロード、インストール
最新版のSwiftのスナップショットを手に入れましょう。Swift.org からApple Platforms Xcode Swift Development Snapshotを選択します。ダウンロード後インストールをして、パスを通すためにターミナルで以下を実行します。
export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:$PATH
そしてswift --version
を実行し、PATHが通っているかを確認しましょう。
よくわからなければ、詳しいことはここを見るとわかりやすいかと思います。
http://qiita.com/hayashikun/items/fddcdb7c2f9c687bcc80
ちなみにOSはEl Capitanじゃないとだめです。アップグレードしましょう。
本題に入る前に
Hello Server Side Swift ここをみればVaporの概要はわかりますし、今回やろうとしていることはそれと同じです。本記事では、詰まりどころや必要知識を補足しながら書いていきたいと思います。
まず、サーバーサイドの開発をするならば、そもそもXcodeは使うの?という疑問が出てくると思いますが、安心してください、使います。基本はXcodeでローカルで開発をして、サーバーにデプロイ作業をするという流れになります。今回はHerokuに上げました。
自分でUbuntu上にデプロイする作業が思った以上に詰まりどころが多く、初めはPerfectでAPIを書いていたのですが、デプロイ作業が面倒すぎてとりあえずそういうのが苦手な方はVaporのほうが良いと思います。Herokuに簡単に上げれますしすぐ動きます。しかもVaporのほうが直感的にやりたいことが書けるのでわかりやすいです。
Railsを使ったことがある人ならイメージが湧きやすいと思いますが、rails sでローカルサーバーを立てて作業をして、本番はHerokuにあげるというようなことを、この記事でしています。
本題
説明が長くなりました。では、始めていきます。まずはXcodeで新規プロジェクト (File > New > Project)を作成しましょう。
templateは OX X > Application > Command Line Toolを選択します。
プロジェクト名はServerSwiftTestにしました。プロジェクトを作成すると、以下のようになっていると思います。
まずはじめに何をするかといいますと、Vaporをインポートします。今まで、Swiftでライブラリをインポートする際にはCocoaPodsやCarthageを使っていたと思いますが、Swift Package Managerというものを使います。
これはSwiftのモジュールを管理するツールで、モジュールのダウンロード、コンパイル、リンクを行ってくれます。
- http://kostiakoval.github.io/posts/swift-package-manager/
- http://llcc.hatenablog.com/entry/2015/12/10/232643
- http://qiita.com/hayashikun/items/fddcdb7c2f9c687bcc80
を参照すると使い方などが理解しやすいかと思います。
それでは、VaporをPackage Managerを使ってインストールしていきます。まず、Sourcesディレクトリを作成し、main.swiftをそこに移動させます。次に、Package.swiftを作成しプロジェクトルート配下に配置させます。下図を見ればわかると思います。
Package.swiftには
import PackageDescription
let package = Package(
name: "ServerSwiftTest",
dependencies: [
.Package(url: "https://github.com/tannernelson/vapor.git", majorVersion: 0)
]
)
と書きます。
Main.swiftには
import Foundation
import Vapor
print("Hello, World!")
Route.get("hello") { _ in
return ["Hello" : "World"]
}
let server = Server()
server.run(port: 8080)
と書きます。
これは https://github.com/tannernelson/vapor#json を見ればわかると思いますが、/hello にアクセスすると["Hello" : "World"]
というJSONを返すAPIです。
ビルドの準備
Package Managerを使ってビルドをする際に、Import Pathsを設定する必要があります。
以下のようにBuild Settingsを開き、import pathsと検索窓に入力し該当箇所に移動します。$(SRCROOT)/.build/debug
、$(SRCROOT)/.build/release
と記入してください。
次にターミナルを起動します。プロジェクト直下まで移動し(cd ServerSwiftTest)、swift build
を実行すると、ビルドが行われ,.build
ディレクトリができます。
その後.build/debug/ServerSwiftTest
を実行するとローカルサーバーを立てることができます。
そして、localhost:8080/hello
にアクセスすると以下のようになっているかと思います。
ローカル環境ですが、JSONを返すAPIを作成することができました。行数も少なく、とても簡単に作れました!次はHerokuにあげて、どこからでもアクセスできるようにしていきましょう。
Heroku準備
Procfileをプロジェクトルートに作成します。Vimなどのテキストエディタで作成したら大丈夫です。
web: ServerSwiftTest --port=$PORT
と書きましょう。ServerSwiftTestはプロジェクト名なのでそれに合わせましょう。
このファイルは、HerokuにServerSwiftTestを実行するように伝える役割があるみたいです。
synxを使って、ディレクトリを整理しています。
http://qiita.com/Yuta/items/fdce62fcb871912629ce これをみればわかると思います。
別に整理しなくてもXcode上でSourcesを作成していたら問題はないとは思いますが念のため。
Buildpack
HerokuにはBuildpackというものがあります。これはアプリケーションをデプロイするたびに、コマンドを実行することができるものです。これでSwiftなどをHeroku上にインストールしています。
https://github.com/kylef/heroku-buildpack-swift ここに、Herokuのbuildpackがあります。Herokuでappを作成した後、プロジェクトルート直下で
heroku buildpacks:set https://github.com/kylef/heroku-buildpack-swift.git --app server-swift-test
を実行します。今回は、server-swift-test
がapp名です。
実行すると以下のようになります。
Herokuへup
git push heroku master
を実行するとHerokuへpushができますが、まだコミットしていないと思いますので、コミットをしましょう。また、heroku git:remote -a server-swift-test
を実行し、今のプロジェクトのgitのremoteを作成したappにします。
git push heroku master
を実行
これでHerokuへupできました!!
https://server-swift-test.herokuapp.com/hello
へアクセスしてみるときちんとJSONを返してくれています!もちろんこれは私のappなので、是非ご自身で試してみてください。
さいごに
以上になります。コード行数も少なくて簡単にJSONを返すAPIサーバーをSwiftで書くことができました。参考になれば幸いです。