【Swift】OpenAPIGeneratorにPRを出してみる

いくつかのiOSアプリ案件でOpenAPIGeneratorを使ってswift4のAPIクライアントを自動生成しているのですが、とても快適です。

利用状況はこんな感じ

- OpenAPIClientで生成したファイルは、〇〇(プロジェクト名)APIClientとしてプロジェクト本体のレポジトリとは別のレポジトリとして管理
- SwiftPackageManagerに対応させて、SPM経由でプロジェクトからimportできるように
- `update.sh` というシェルを○○APIClientディレクトリのルートにおいて、実行してタグ更新するだけでAPIの更新が出来るようにし、人依存を撤廃
- いくつか都合が悪いところは、static var の部分を修正して、カスタマイズして対応。(BuilderFactoryを丸ごと切り替えられるようになっているので、最終的に全部カスタマイズ可能な作りになっていてとても便利です)

別レポジトリに切り出したのは、APIClientはプロジェクトの内部構造に依存せず独立運用可能なので、切り離して運用する事でプロジェクトレポジトリの複雑度をむやみに上げないためというのが1つと、swift4のgeneratorがAlamofireの古いバージョンを利用しているのですが、プロジェクトディレクトリからどのバージョンのライブラリを使っているとかを一切意識せずに使えるようにしたかったからです。余計な依存性を含めたくありませんでした。

ただ、使っていて2点だけ困るところがあったので修正リクエストを送ってみようと思います。内容は以下です。

1. レスポンスを受け取るQueueが選択できず、常にメインスレッドが使われるので切り替えられるようにしたい。
2. RequestBuilder<Any>のときはNonDecodableBuilderになって欲しい。

ただ、ちょっと敷居が高くて手を出しにくいOSSに感じるので再現できるように自分の体験した手順を公開しながら進めて行こうと思います。

今回は1.のスレッドの件を題材にします。

それでは進めていきます。

# 1. Fork
プロジェクトをforkします。

# 2. Swift4のMustacheを管理しているディレクトリを発見する
まず、これがなかなか見つかりませんでした。

「GitHub OpenAPIGenerator Mustache」とグーグル検索して、色々ディレクトリを掘って探していると[modules/openapi-generator/src/main/resources](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator/src/main/resources)の下に見つけられました

#3. レスポンスを受け取るQueueを選択できるようにしてみる
コールバックをmainキューに指定できるのはネットワークのライブラリではよくある事です。ただ、利用側が任意に切り替えられないのが不便だと思った点でした。そこでmasterブランチからresponse-queueというブランチを切って、提案を出してみようと思います。

カスタマイズ可能な仕組みの `open class {{projectName}}API` に対して、 

```swift:
public static var queue: DispatchQueue = .main
```

という記述を加え、通信を行う `AlamofireImplementations.mustache` の中で、Alamofireに対してqueueを渡して通信するようにしてみます。

いくつか変更を加えてみました。

https://github.com/syatyo/openapi-generator/commit/41428e08a6763c76df296d12c1235fe20d5ccfa1

https://github.com/syatyo/openapi-generator/commit/dac4f48c480dabcc07a2d1945feb31b24997f859

# 4. 自動生成を試してみる
みた感じうまくいってそう。

```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g swift4 -o ~/Desktop/TestAPIClient
```

# 5. PRを出そうとする...前の準備
PRを出す前に、プロジェクト規約がしっかり決まっているようなので、こちらのファイルを良く読んでみます。
https://github.com/openapitools/openapi-generator/blob/master/CONTRIBUTING.md

[Before Submitting PR](https://github.com/openapitools/openapi-generator/blob/master/CONTRIBUTING.md)を読むと、「PR出す前にissue探してなかった場合はまずissue立ててくれ」と書いてあるので、issueを立ててみました。

割と支離滅裂な英語かもしれませんが、とりあえず書きたい事は書きました。
https://github.com/OpenAPITools/openapi-generator/issues/4590


次にテストの章を実行していきます。
## PetStoreのサンプルをアップデート
こちらを実行すれば良いっぽいです。

`./bin/swift4-all.sh`

## テスト実行
テスト実行用の便利なshellを発見したので、これを使っていきます。
`samples/client/test/swift4/swift4_test_all.sh`

自分の場合Xcode11を使っているからかテストかうまく終わらず、理由もエラーを読んでも特定しにくいものだったので、`samples/client/petstore/swift4/default/SwaggerClientTests/SwaggerClient.xcworkspace`を開いて、Xcodeから直接テストを実行しました。

特にテストケースの追加はしていないのでこのままコミットを行います。

# 6. 準備ができたのでいざPR
一通りガイドラインの準備事項が終わったので、PRを出していきます。

PRを出す時のチェックリストがあるのでいくつか雑に翻訳してながら見ていきます。

- ガイドライン読んで従ってね
- プロジェクトのビルドしてね
- サンプルの再出力してね
- 正しいブランチにPR向けてね
- コミッターの一覧に入ってる言語ごとのレビュワーを全部コピーしてメンションしてね

ざっくりこんな感じのはず。

全部確認したのでPRを出します。

# 完了！
https://github.com/OpenAPITools/openapi-generator/pull/4591

無事、PRを出すところまでは成功しました。ガイドラインが厳しめで結構大変でしたが、ほっと一息。

なんかビルドエラー出てるけど明日考えよう。何回か修正するとしても、マージまでいけると嬉しいなー。

それではお付き合いありがとうございました！みなさんがPR出す時のヘルプになれば良いと思います！

# PS
マージされました！