この記事について
iOSアプリでGraphQLサーバにアクセスするためのクライアントを実装するための導入を書きます。サーバ機能ではなく、クライアント機能の説明です。
- Swift
- iOS15
- Xcode13
なお、サーバ側の実装については【Go言語】はじめてのGraphQLサーバ実装 | gqlgenも記述したのでご覧下さい。
手順
Apollo-iosパッケージのインストール
GraphQLのライブラリではおなじみのapolloを利用します。
XcodeのFile -> Add Packages を開き、apollo-iosを検索してインストールします。
スキーマ定義のダウンロード
apolloコマンドのインストール
apollo
コマンドがインストールされていなければインストールします。インストールにはnode.jsやJavaScriptでの開発でパッケージ管理でおなじみのnpm
を使います。(npmコマンドのインストールについては割愛させていただきます。)
$ npm install -g apollo
スキーマのダウンロード
GraphQLサーバに向けて下記のコマンドを実行します。ここではschema.json
ファイルにスキーマ定義が全て記述されます。
$ apollo schema:download --endpoint=http://localhost:8080/graphql schema.json
schema.json
をXcodeプロジェクト内に設置します。デフォルトではビルドターゲットのアプリの階層直下に保存します。つまり*.xcodeproj
ファイルがある階層の次のディレクトリです。(Assets.xcassetsディレクトリがある階層に保存)
ビルド設定の追加
ここが難所です。Apollo公式ドキュメントの「Adding a code generation build step」と併せてご覧下さい。
- ビルドターゲット・アプリケーションのBuildPhasesを開きます。
- BuildPhasesで「+」ボタンをクリックし「New Run Script Phase」を選びます。「Run Script」が追加されます。
- 追加された「Run Script」を「Generate Apollo GraphQL API」に名称変更します。
- タイトル部分をクリックすると変更できます。
- あくまでも開発者が見て分かりやすい名前にします。
- 「Generate Apollo GraphQL API」を既存項目の「Compile Sources」の上に移動します。
-
Apollo公式ドキュメントの「Swift Package Manager Run Script」を画面のフォームに貼り付けます。
- (必要に応じて)最後の行でschema.jsonのパスを編集します。
- (必要に応じて)最後の行で生成されるSwiftファイルのパスを編集します。
ビルド
通常通りアプリケーションをビルドします。API.swift
が生成されます。ただ、プロジェクト内では管理されていないのでfinder等でソースコードを確認したら、Xcodeのプロジェクトに追加します。
エラー
ここで下記のようなエラーに遭遇しました。こちらの投稿によるとapollo-iosの0.9.5バージョンではSwift5にきちんと対応できていないことが原因のようです。「Update Package」をして0.50.0にしたら解消しました。(2022年1月11日現在)
Cannot convert parent type 'EnumeratedSequence<[Key]>' to expected type 'EnumeratedSequence<IndexingIterator<Array<Key>>>'
クエリの実行
https://www.apollographql.com/docs/ios/initialization/#basic-client-creationにて基本的なクライントの実装方法が説明されています。シングルトン設計にしていますね。
import Foundation
import Apollo
class GqlDriver {
static let shared = ApiDriver()
private (set) lazy var apollo = ApolloClient(url: URL(string: "http://localhost:8080/graphql")!)
}
上記のGraphQL APIドライバクラスに対して下記のようにクエリを実行します。fetch
関数でサーバに問い合わせています。引数のquery
には先ほどの自動生成で作成されたGraphQLクエリを指定します。
func func1() {
GqlDriver.shared.apollo.fetch(query: UserQuery(id:"VXNlcjox")) { result in
switch result {
case .success(let r):
// r に戻り値が含まれるので処理を書く。
case .failure(let e):
print("\(e)")
}
}
}
参考・関連文献
- https://www.apollographql.com/docs/ios/installation/
- https://www.apollographql.com/docs/ios/downloading-schema/
- https://www.apollographql.com/docs/devtools/cli/
- https://community.apollographql.com/t/error-building-swift-project-after-installing-apollo-ios-client/2308/2
- https://www.apollographql.com/docs/ios/initialization/#basic-client-creation
- https://blog.spacemarket.com/code/graphql-on-swift-by-apollo-ios/