LoginSignup
7
3

More than 1 year has passed since last update.

Swift, iOSでGraphQLクライアントを導入する

Posted at

この記事について

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」と併せてご覧下さい。

  1. ビルドターゲット・アプリケーションのBuildPhasesを開きます。
  2. BuildPhasesで「+」ボタンをクリックし「New Run Script Phase」を選びます。「Run Script」が追加されます。
  3. 追加された「Run Script」を「Generate Apollo GraphQL API」に名称変更します。
    1. タイトル部分をクリックすると変更できます。
    2. あくまでも開発者が見て分かりやすい名前にします。
  4. 「Generate Apollo GraphQL API」を既存項目の「Compile Sources」の上に移動します。
  5. Apollo公式ドキュメントの「Swift Package Manager Run Script」を画面のフォームに貼り付けます。
    1. (必要に応じて)最後の行でschema.jsonのパスを編集します。
    2. (必要に応じて)最後の行で生成されるSwiftファイルのパスを編集します。

screen001_アートボード 1.png

ビルド

通常通りアプリケーションをビルドします。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にて基本的なクライントの実装方法が説明されています。シングルトン設計にしていますね。

GqlDriver.swift

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)")
            }
    }
}

参考・関連文献

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3