Help us understand the problem. What is going on with this article?

【Server-side-Swift】【Vapor】iOSアプリエンジニアが挑戦する初めてのサーバーサイド【勉強会レポ】

More than 1 year has passed since last update.

はじめにの前に(概要/対象読者)

概要

  • SwiftでサーバーサイドAPIの開発ができる
      -> サーバーサイドの知識があまりなくても開発できちゃう
  • Swiftすごい、Vaoprすごい

対象読者

  • Swiftの基本的なコーディングを経験した人
  • サーバーサイド知識はあまりないが(Swiftを用いた)サーバーサイドの構築に興味がある人

※今回の勉強会で使用したコードは以下に置いています。Vaporで生成されたコードをちょっといじっただけですが。
https://github.com/s-kamada/Swift-server

あくまでレポなので勉強会の内容に合わせて記述します。

はじめに

今年の3月に大学を卒業し、4月からアプリを作る会社に入社した者です。
まだ研修期間中なのですが、研修では所定の要件に沿ったiOSアプリとAndroidアプリを製作しています。

先日研修のiOSアプリの製作が終了し、「Swiftの知見をさらに深めたい!」ということでこちらの勉強会に参加してきました。
iOSアプリエンジニアが挑戦する初めてのサーバーサイド(connpassリンク)
スライド(SlideShare)
スライド

大学時代にエンジニア志望の仲間として緒に勉強していた友人が講師役の勉強会です。
生粋のiOS/Swiftエンジニアですが普段は睡眠とAIを掛け合わせた研究をしているんだとか。

Swiftでサーバーサイドを作れるらしい

Swiftで書くと何がいいの?

  • 早い

Swiftは4秒で終了しました。 Javaは4.3秒と、ほぼ同じぐらいです。このテストにおけるSwiftとJavaの性能はほぼ同じですね。Node.jsを見てみましょう。15.8秒かかっています。SwiftやJavaの約4倍ですね。Rubyはどうでしょう。とても遅いです。1

  • 省メモリ

RSS(ベンチマークを実行するのに必要な物理メモリ領域)のベンチマークを見てみると、Swiftでは15MBで、Javaでは32MBです。必要なメモリはJavaの半分なのに、同じ性能です。Node.jsはJavaよりは若干少ないですが、Swiftよりずっと多いです。Rubyはたくさん必要ですね。1

なんでVaporなの?

Server-side-swift のフレームワークは数多あるけれど

  • perfect
  • Swifton
  • Slimane
  • Express
  • HTTPSwiftServor
  • Kitura
  • Vapor etc......

主流はKitura、Vapor。
海外ではVaporの方がファンが多く、サーバーサイドの知識があまりない人はVaporの方がいい、ただしVaporの方がSwiftのアップデートへの対応が早いが、開発者もそれについていくためのコストがかかる、など長短あるようです。2

Vaporを使う

※ Homebrew、Swift/Xcode(4.1.0以上)がインストールされている前提です

構築

インストール

$ brew install vapor/tap/vapor

プロジェクト作成

$ cd [プロジェクトを置きたいディレクトリ]
$ vapor new [プロジェクト名]

イカしたロゴとともにプロジェクトが生成されます
スクリーンショット 2019-05-22 14.09.39.png

プロジェクトを開く(Xcode)

すこし時間がかかります

$ vapor xcode
Generating Xcode Project...
Open Xcode project?
y/n> y
Opening Xcode project...

プロジェクト構成

スクリーンショット 2019-05-22 14.51.37.png
基本的に編集するのはAppフォルダ内のファイルです
Controllersはコントローラ、Modelsはモデルを入れるフォルダ、など見た通りの命名がされています。

コーディング(抜粋)

自動生成されたものだけも十分動きますが、ちょっといじります。
今回は「Todo管理アプリ」のサーバーサイドAPIを作成する前提で編集します。

モデル

TodoModel.swift
final class TodoModel: SQLiteModel {
    /// The unique identifier for this `Todo`.
    var id: Int?
    /// A title describing what this `Todo` entails.
    var title: String
    var isFinished: Bool

    /// Creates a new `Todo`.
    init(id: Int? = nil, title: String, isFinished: Bool) {
        self.id = id
        self.title = title
        self.isFinished = isFinished
    }
}

データモデルです。マイグレーション(自動的にデータベースの更新・管理を行う)などのextensionも実装できます。

コントローラ

TodoController.swift
final class TodoController{

    /*中略*/

    //新しいTodoを生成する
    func create(_ req: Request) throws -> Future<Todo> {
        return try req.content.decode(Todo.self).flatMap { todo in
            return todo.save(on: req)
        }
    }

    //すでに登録されているデータを更新する
    func update(_ req: Request) throws -> Future<Todo> {
        return try flatMap(to: Todo.self, req.parameters.next(Todo.self), req.content.decode(Todo.self)) { todo, updateTodo in
    todo.title = updateTodo.title
    todo.isFinished = updateTodo.isFinished
    return todo.save(on: req)
        }
    }
}

データの読み込み、生成、削除の操作は自動で生成されますが、不足しているので更新処理を追記しました。

ルーティング

routes.swift
public func routes(_ router: Router) throws {
    // そのエンドポイントのルートにアクセスした場合
    // Basic "It works" example
    router.get { req in
        return "It works!"
    }

    // http://(エンドポイント)/hello/world にアクセスした場合
    // Basic "Hello, world!" example
    router.get("hello","world") { req in
        return "Hello, world!"
    }

    // http://(エンドポイント)/todos に対してAPIを叩く場合
    // Example of configuring a controller
    let todoController = TodoController()
    router.get("todos", use: todoController.index)
}

ルーティングを定義するファイルです。

ビルドしてサーバーを立てる

左上のバーをRun > My Macと設定してビルドします。この場合はlocalhost:8080にサーバーが立ちます。
ターミナル上でもビルドが可能ですがXcode上でビルドするよりも時間がかかるようです。

$ vapor build
$ vapor run

動いたか確認してみる

ブラウザでlocalhost:8080に移動してみると...
スクリーンショット 2019-05-22 15.45.02.png
動いてるみたいですね :dancer:
他のAPIも叩いてみます。ここからはAPIツールのPostmanを使用します

  • 追加
    スクリーンショット 2019-05-22 15.50.07.png

  • 一覧取得
    スクリーンショット 2019-05-22 15.51.53.png
    レスポンスが帰ってきているのがわかりますね :dancer:

まとめ

  • サーバーサイドAPIをSwiftだけで簡単に作れる。やったね! :dancer:
  • 課題(今回の勉強会では触れなかったこと)
    • DBとの連携が必要(今回はしていません。連携の設定をしないとXcodeを落とした際にデータがリセットされます)
    • マイグレーションの方法
    • デプロイ方法

  1. Try! Swift NYCの講演より。現在は少し記録が更新されているようですが、やはりSwiftは早いかつ省メモリなようです(The Benchmarks Game) 

  2. ここHacking with Swiftなど、KituraとVaporを比較考察している記事が多いです。 

s-kamada
アプリつくるひと2年目(swift / java / Kotlin) ほんとうは言語仕様の深いところを掘る、みたいなニッチ&ギークだけど為になる記事を書けるようになりたい
https://github.com/s-kamada
caraquri
ネイティブモバイルアプリの開発を強みとする港区の開発会社。
https://caraquri.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away