VS CodeでiOSアプリ開発をする~Github Copilotを添えて~

# はじめに
これはTDCソフト株式会社アドベントカレンダー2024 の6日目の記事です。
とある記事でVS CodeでiOSの開発をしている記事[^2]を見つけたので、そちらを参考にさせていただきつつ、Copilotを導入し、サクサク開発できる環境を作ってみました。

# 環境
- MacOS
    - Sequoia 15.1
- Xcode 16.1
- VS Code 1.95.3

# SweetPadの環境構築
SweetPad[^1]の公式ページから導入する
https://sweetpad.hyzyla.dev/docs/intro
VS CodeのMarketplaceで`Sweedpad`をインストールします。

# プロジェクトの作成
SweetPadのインストールが完了したら、VS Codeで開くためのプロジェクトを作成します。
作り方としては、Xcodeでプロジェクトを作る or CLIで作るになります。
Xcodeから作るのはいつでもできる、かつ、簡単にできるのでCLIでやってみます。
公式に書いているのは、XcodeGen or Tuist[^3]というCLIでした。
XcodeGenは過去にやったことあるからTuistでやってみます。

## Tuistの環境構築
Tuistのページを見つつ、順番に実行していきます。
一旦Homebrewでインストール
```bash
brew tap tuist/tuist
brew install --formula tuist
```

Homebrew経由でインストールしたのでZshのシェル補完を設定する
```bash
mkdir .oh-my-zsh/completions
tuist --generate-completion-script > ~/.oh-my-zsh/completions/_tuist
```

## Tuistでプロジェクトの作成
Tuistが使えるようになったので、プロジェクトの作成作業に入っていきます。
まずは、アプリのプロジェクトファイルを作成するディレクトを作成しておきます。
私はホームディレクトリに`Develop`というフォルダを作成し、そこで作業しました。
```bash
mkdir SweetpadSample
cd SweetpadSample
tuist init --name SweetpadSample
```

initすると下記のように自動でディレクトリが構成される
```bash
ls
Project.swift  SweetpadSample Tuist Tuist.swift
```
- Project.swift
    - ライブラリの依存関係、ローカライズされたリソースファイル、その他の構成オプションが設定されている
    - Package.swiftと一緒
- Tuist.swift
    - プロジェクトスコープのTuistの構成が含まれている
    - 何のこっちゃよく分からない
- SweetpadSample
    - アプリのソースファイルが含まれているディレクトリ


プロジェクトファイルを作成する準備が出来たので、生成してみましょう。
プロジェクトファイルを生成するコードを実行するコマンドを打ちます。
```bash
tuist generate
```
.xcodeprojと.xcworkspaceが作成されます。
```
ls
Derived Project.swift SweetpadSample SweetpadSample.xcodeproj 
SweetpadSample.xcworkspace Tuist Tuist.swift
```
Deriverdというディレクトリも作成されているが、何のためにあるのか分からないので、一旦スルーします。（ちゃんと勉強します、、、）

:::note warn
直接開いて編集できるXcodeプロジェクトとは異なり、Tuistプロジェクトはマニフェストファイルから生成されることに注意してください。つまり、生成されたXcodeプロジェクトを直接編集しないでください。
:::

下記は、Tuistのページに書いてあったおまけです。
# Tuistの一般的なコマンド（おまけ）
## アプリのビルド
```bash
tuist build
```

## アプリのテスト
```bash
tuist test
```

ここまでやってようやくVS Codeに移れます

# VS CodeでSweetPadの設定をする
Tuistで作成したプロジェクトファイルのルートファイルをVSCodeで開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/1200fbc6-c894-aaa3-f46c-5adc7e99c480.png)

SweetPadを正常にインストール出来ていれば、左のサイドバーにキャンディーのアイコンがあり、それをクリックすると、ビルド＆Runするアイコンと、実行できるSimulatorとデバイスのリストが表示される。
Destinationsで任意のSimulatorにカーソルを当てると再生ボタンが表示され、クリックするとそのSimulatorでアプリが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/0b781dd3-cee0-a7e4-358c-b598ad2c2d9d.png)

ここまで出来たら開発可能な環境のセットアップは完了です。
とはいえ、ここまでだったらXcodeでいいじゃんとなるので、その他の機能も追加していきましょう。

## オートコンプリート機能の設定
1. MarketPlaceでSwiftのインストール
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/b09ab5e6-c847-9b0f-d199-56c4f827172c.png)
    1. インストールするとCodeLLDBを使うのに、GlobalかWorkspaceで使うかを聞かれたが、一旦怖いのでWorkspaceに設定しました。
1. `xcode-build-server`をHomebrewでインストール
    ```bash
    brew install xcode-build-server --head
    ```
1. コンフィグファイルをVS Codeのコマンドパレットから作成する
    1. **SweetPad: Generate Build Server Config**
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/3f28a8dc-a68b-9f55-9a99-4c98ee83544b.png)
1. キャンディマークのスパナのアイコンをクリックし、ビルドをするとSuggestが出るようになる
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/aeda2be7-68a0-1d08-9b2b-2db8ac360d85.png)

## デバッグ
プロジェクトのルートディレクトリにある`.vscode`の中に、`launch.json`ファイルを作成します。
公式ページに記載されているjsonをコピペし、`F5`を押すとデバッグビルドが実行されます。
ブレークポイントなどで変数などの確認はできますが、画面の構成や、Memory Graphは見られなさそうなため、そこはXcodeを使った方が良さそうです。

## コードフォーマット
Apple公式のフォーマッタである`swift-format`やその他の拡張機能を⌘+Sで機能させます
`.vscode/settings.json`に下記を追記します
```
{
  "[swift]": {
    "editor.defaultFormatter": "sweetpad.sweetpad",
    "editor.formatOnSave": true,
  },
}
```
自分の環境だとすでに他の設定がされているため、こんな感じで追記しました。
```json
{
    "lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB",
    "lldb.launch.expressions": "native",
    "[swift]": {
        "editor.defaultFormatter": "sweetpad.sweetpad",
        "editor.formatOnSave": true,
    },
}
```
これで⌘+Sを押すと自動的にフォーマットされるようになりました。
swift-formatが気に入らず、swiftformatを使いたい時は、
```json
{
  "sweetpad.format.path": "swiftformat",
  // The "--quiet" flag is important here to ignore output that "swiftformat" writes to stderr.
  // Otherwise, the extension thinks that the formatting failed and shows an annoying error message
  "sweetpad.format.args": ["--quiet", "${file}"],
}
```
と書けばいいらしいです。
swift-formatのフォーマットのルールを変えたい場合は、`.swift-format`というファイルを作成し、その中にルールを記載すればいいですが、割愛します。詳しくは[こちら](https://github.com/swiftlang/swift-format)をご覧ください。

## VS CodeからTuistを操作する
コマンドプロンプトでTuistのコマンドが打てます。
- sweetpad.tuist.generate 
    - SweetPad: Generate an Xcode project using Tuist
    - プロジェクトの作成
- sweetpad.tuist.install
    - SweetPad: Install Swift Package using Tuist
    - パッケージをインストールする
- sweetpad.tuist.clean
    -  SweetPad: Clean Tuist project
    -  クリーン
- sweetpad.tuist.edit
    - SweetPad: Edit Tuist project (Open project in Xcode)
    - Tuistの何かを編集できる
`.vscode/settings.json`に
```bash
"sweetpad.tuist.watcher": true
```
としておくと、`.swift`ファイルを消したり追加した際に自動的にプロジェクトファイルを再生成してくれるようになるようですが、ビルドをするとファイルを追加しても認識されなかったので、この設定だけでは不十分な可能性があります。
（`"sweetpad.tuist.autogenerate": true`でもダメでした）
その他にも、設定した方がいいことはありますが、ただでさえ長くなっているのであとは[こちら](https://sweetpad.hyzyla.dev/docs/intro)のページから設定してください

# Github Copilotでコードを書いてみる
1. Github Copilotの購入
    1. Github Copilotのページから住所やらクレジットカードを記入する
1. ボタンをぽちぽちして、VS Codeにインストールする的なリンクを押すと、Githubの認証が入り、認証が通るとVS Codeが開く
1. Marketplaceで`Github Copilot`をインストールする

これでCopilotの設定は一旦OKです

## コードを生成してみる
1. 新しいファイルを作成します
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/3fa353eb-7faa-7eb1-c1d4-997024143651.png)
1. ⌘+Sを押して、適当に`LoginView.swift`と命名します
1. ⌘+iを押して、Copilotの会話Viewを表示します
1. 命令してみる
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/566985a6-71d3-a560-1512-50edc64fcf01.png)
1. 作成されたコードに同意する
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/6b652d23-28e4-051c-c0aa-0e674395d4a7.png)
1. `ContentView.swift`から先ほど作成した`LoginView`に遷移するコードを書いてもらう
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/4c6796f3-7886-9884-15e7-48bc20529994.png)
1. LoginViewを新しく作成してしまっているので、いい感じのところをコピペする
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/9d6201d8-8c8d-0cfb-fb77-cd5f7dc30034.png)
1. 実行してみる
1. ビルドエラー、、、
1. LoginViewがないと怒られていたので、ファイルを追加しても認識してくれていなかった
1. VS CodeからTuistを操作するでやった自動的にプロジェクトファイルを再生成するのが、機能していなかったので、仕方なくコマンドパレットで`SweetPad: Generate an Xcode project using Tuist`をして、プロジェクトを再生成しました
1. 再度実行したら表示された！
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/31490d2f-28df-167e-af90-6ca4fa5d4105.png)
1. ボタンを押したら、ちゃんとLoginViewに遷移できていますね
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/2ce5e7f1-834c-dafd-b356-5cd55b51cce7.png)
    1. LoginViewもちゃんと動いてそうです
    1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179037/e1dcc502-637b-791d-2c46-593a503d0c27.png)
細かい部分は自分で手を加える必要がありますが、大枠を作成してもらうのは、非常に楽になりましたね。（ものすごく今更実感していますが、、、）

# まとめ
だいぶ長くなってしまいましたが、VS CodeでiOSアプリを開発する方法でした。
1番の利点としてはコード生成が1つのエディタで出来るようになったことだと感じています。
一応[Github Copilot for Xcode](https://github.com/github/CopilotForXcode)がありますが、サードパーティのXcode入れるのに抵抗があったので、今回VS Codeでアプリ開発が出来るようになったのは、喜ばしい限りでした。（なぜ抵抗あるのかと言われてしまうと、なんとなくになってしまうのですが、XcodeはAppleがいい、、、）
ただし、Hierarchy ViewやGraph Memoryが使えない点などを挙げると、Xcodeを全く使わなくて済むようになるかと言われるとまだまだそこまでではないと思います。
今後機能が増えることを信じて、個人開発ではVS Codeに移行してみようかなと思いました！
感想や指摘をコメントで頂けると勉強になりますので、ぜひお願いいたします！

# 参考文献
[^1]:Sweetpad. https://sweetpad.hyzyla.dev/
[^2]:aromarious. もうVS Codeなしでは生きていけない. https://zenn.dev/aromarious/articles/sweetpad-extension-introduction. 2024/12/02. (参照 2024/12/06)
[^3]:Tuist. https://tuist.dev/