忙しい人向けの Use Swift on AWS Lambda with Xcode - #WWDC20

画像29

サーバレスとSwift

Server コンポーネントは Client の機能を拡張することができ、デバイス上では行えない作業や重い処理を扱うことができる。

画像1

サーバレス機能はイベントドリブンで動作する。スケールしやすくコストコントロールもしやすい。AWS Lambda はこの分野のリーダー的な存在。

画像2

サーバレス機能は、コストに直接影響するコンピューティングリソースに注意を払う必要がある。Swift は『開発者の利便性』と『低リソース』を同時に実現しており、サーバレス機能に向いている。

画像3

Swift on AWS Lambda

このようにたった4行で記述できる。イベントペイロードが処理できるようになるとクロージャが呼び出され、ランタイムライブラリが AWS Lambda のプラットフォームと相互作用を管理する。

画像5

より繊細なパフォーマンスが必要な場合のために、SwiftNIO を活用した Protocol ベースの API も提供している。これはネットワーク処理スタックと同スレッドで動作するためコンテキストスイッチを防げる。しかし、イベントループをブロックしないように注意する必要があり、複雑になる。

画像6

ほとんどの場合はクロージャベースの API が適している。この例ではリクエスト・レスポンスの構造体を Codable に準拠し、JSON のシリアライズ・デシリアライズをかんたんに実現している。

画像7

Xcode で開発するデモ

Xcode で開発する方法を見ていく。このワークスペースには iOS / Lambda の2つのプロジェクトが含まれており、Lambda プロジェクトは Swift AWS Lambda Runtime に依存している。

画像8

エントリポイントは次のようになる。ここではリクエスト・レスポンス用に2つの構造体も定義している。

画像9

iOSアプリ側は SwiftUI で作成されており、『名前』と『パスワード』を入力してボタンをタップすると、リクエスト用のメソッドを呼び出すようになっている。

画像10

register メソッドと Lambda の実装はどうやって結びつくのだろう?

画像11

試しに Lambda プロジェクトを実行してみると、コンソールにエラーが出力される。これは実際の AWS Lambda 上ではなく、Xcode 上で動作させているためだ。

画像12

幸い、ランタイムライブラリには AWS Lambda のランタイムエンジンをシミュレーションするモードが備わっており、環境変数 LOCAL_LAMBDA_SERVER_ENABLED = true で有効にできる。

画像13

この状態で実行すると、ローカルの7000番ポートをリッスンし、/invoke エンドポイントでイベントを待ち受けているのが分かる。

画像14

先程の register メソッドの実装は次のようになる。通常の URLSession を利用して http://127.0.0.1:7000/invoke にリクエストしている。動作確認のため、このメソッド内と Lambda 関数内にブレークポイントを設定しておく。

画像15

iOSアプリを起動すると、Xcode は2つのプロセスを管理しているのが分かる。また、Lambda 側はわずか 6.3MB で動作していることも分かる。

画像16

シミュレータで『名前』と『パスワード』を入力して、登録ボタンをタップすると・・・

画像17

最初のブレークポイントに止まる。処理を継続すると・・・

画像18

今度は Lambda 関数側のブレークポイントに止まる。LLDB でリクエストの中身を確認すると、入力した値が入っている。さらに続けると・・・

画像19

request メソッド側のレスポンス処理の部分で止まる。続けると・・・

画像20

アプリ側にレスポンスの結果が表示された。

画像21

仕組みはこう。環境変数でローカルデバッグモードを指定することで、ローカルに HTTP サーバを立ち上げ、AWS Lambda ランタイムエンジンをシミュレートすることで、iOSアプリからの HTTP リクエストを処理する。

画像22

AWS へのデプロイ

実際に AWS にデプロイするには AWS CLI などのツールを利用する必要がある。ここではそれをラップした簡易なスクリプトで実行する例をみる。

画像24

流れは次のようになる。

1. Amazon Linux2イメージをベースにした Docker イメージをビルド。
2. Dockerコンテナ内で、作成した Lambda 関数をコンパイル。
3. 実行ファイルと依存リソースを zip でアーカイブ。
4. zip を AWS にアップロードして、最新のコードとして更新。

画像23

仕組みはこう。AWS API Gateway が HTTP リクエストを待ち受け、イベントがキューに格納されたら Lambda Runtime Engine がそれを取得し、HTTP コールとして Lambda 関数を呼び出す。

画像25

我々がやった2つのこと

これらを実現するために私達は大きく2つのことをした。1つ目は、Amazon Linux 2 イメージ向けの Swift ツールチェーンを公開した。

画像26

2つ目は、Swift 向けの AWS Lambda Runtime ライブラリの公開。

画像27

ライブラリは多階層の API で構成されており、AWS Lambda 上で効率的に動作するように様々な注意が払われている。例えば、プロセスが長寿命の場合にはネットワークコネクションをキャッシュしたりなど。

画像28

AWS プラットフォームとの統合も用意されており、S3 などの他サービスや、カスタムイベントにも対応できる。

画像29

まとめ

Swift は高速・安全・低リソースだからサーバレスに向いている。今日からつくれる状態だから是非試してみてね。

免責

・本記事は公開情報のみに基づいて作成されています。
・要約(意訳)のみなので、詳細はセッション動画をご確認ください。


役に立った記事などありましたらサポート頂けると嬉しいです。