11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OPENLOGIAdvent Calendar 2023

Day 16

macOSアプリ開発初心者がSwiftUIを使ってアプリを作ってみた

Last updated at Posted at 2023-12-16

今回SwiftUIを使って初めてmacOS用のアプリを作りに挑戦してみました。

普段はPHP、Python、TypeScript、JavaScript等でWebアプリ開発をしております。
その視点で今後SwiftUIで試してみたい人が検討できるような情報を感想少し残しておこうと思います。

最後にどんなアプリを作ったのかについては少し記載しますが、ざっくりどんなアプリを作ったのかというと、ChatGPTのレスポンスメッセージビューアプリです。
こんな感じで、コマンドで呼び出してレスポンスメッセージを閲覧できるようにするというアプリです。
対話型のChatGPTクライアントはたくさんあるのですが、簡易なメッセージビューアプリというのは見つからなかったのでSwiftUIへの入門として作ってみました。

qiita.gif

デスクトップアプリのフレームワーク選定

そもそもSwiftUIでデスクトップアプリを作る必要があるのか

いきなりSwiftUIについての内容ではなくなってしまうのですが、これについてまずは一番最初に検討しました。
「macOS用のアプリだからSwift/Objective-Cで作るんだよね」となるのはやや早計で、作りたいものによっては代替的なフレームワークも存在します。

代表的なものとして最近はTauriが人気の印象です。コアプロセスはRustで記述する必要がありますが、UI側はJSで作成することができ、フレームワークが非常に開発のしやすいツールを備えています。(ホットリローディングなど)
他にもElectronもあります。

これらのフレームワークを使えばクロスプラットフォームのアプリを作ることができます。

それでもSwiftUIを使う理由

今回それらのフレームワークと比較してSwiftUIを使いました。
Tauriは非常に優秀なフレームワークですが、それでも一部OSネイティヴな制御はできません。
今回やりたかったウィンドウの厳密な制御(ウィンドウがメインウィンドウではなくなった時の制御等)がTauriだとできませんでした。
Tauriでもできることは多いですが、細かい制御やmacOS依存の機能を使いたい時にはSwiftUIを使う方が後々問題にはならないと思います。

SwiftUIを使ってみての感想

IDE

SwiftUIのIDEについて調べてみましたが、ほぼXcode一択だと思います。
JetBrainsのAppCodeというIDEがあります。現在でもトライアルで使えるため試してみたのですが、非常に良いものでした。
ただ昨年販売を終了したようです。
それによって、デバッグやコード補完などのパワフルさでXcode以外の選択肢はない状態と思われます。

ちなみにXcodeにはVimモードがあります。ただし、Vimの設定ファイルを読み込んだりはできないので、素のVimで使うしかありません。

Webアプリ開発ではIDEがどれかに縛られるということは基本的にないと思いますので、この開発環境的な選択肢の少なさは若干辛い点かもしれません。

情報の少なさ

今回SwiftUIでアプリを作ってみて一番難しかったのがこの点です。
私が情報の手に入れ方、調べ方が下手なのかもしれないですが、SwiftUIについては情報が少ない印象でした。
もちろんSwiftUIの基本的な作り方などの情報はありますが、Webアプリの人気フレームワークで検索した時などと比べると情報は少ない印象で、Xcodeのエラーメッセージで挙がった内容についての解決策などを見つけるのは難しかったです。
また、特に少し凝ったことをしようとすると、Swiftが用意しているどういうAPIを使えば良いのかなどの情報が全然出てこず苦労しました。
またmacOSのバージョンによって仕様も変わったりすることがあり、以前のバージョンでは動いていたが今は動かないみたいなパターンも出てきたりします。

Apple公式のAPIリファレンスもなかなか読解が難解です。
例えばこれはアプリのウィンドウのクラスの説明のページですが、どういう関数が使えるのかくらいしか記載されていません。
これだけみても何をどうすればよいのか全然わかりません。
https://developer.apple.com/documentation/appkit/nswindow

MDNやフレームワークごとのdocsのようにサンプルコードが記述されたりはないんですよね...。

今回上記のような理由でかなり困ったのですが、ChatGPT等に問い合わせてたりすると、意外に上手く行く方法を提示してきてくれることが多かったです。
これから初めて挑戦してみる人はChatGPTを使いながらというのは一つ助けになるかもしれません。

UI

UIシステムは個人的にかなり良いと感じました。
HTML+CSS+JSの環境でUIを検討する時、UIフレームワークの選択肢がかなり多く、またCSSでの装飾の自由自在であるが故に、デザイナーが熟考したようなUIでないとUIがかなりランダムな感じになってしまったりしがちです。
ただSwiftUIではある程度自由に装飾できるものの、用意されたデザインの装飾でことが足りることが多く、それらで装飾しておけばある程度macOSで使われているような見た目に統一されるので、アプリ内でデザインのコンセプトがランダムに混ざり合っているようなことは発生しづらいように思います。

ビューの作成自体もこれだけでテキスト表示のUIが完成するので簡単です。

struct ContentView: View {
    var body: some View {
        Text("テキスト")
    }
}

ただし、サイズ調整がHTML+JSと比べると難しいです。
特にある要素の高さが可変するようなビューを作る時には想像以上に難しかったです。(今でもサイズ調整についてはあまり理解できていません...)
JSを使う場合は、ある要素を取得してその高さを取得して、それを使って別の要素のサイズを変更するというようなこともできますが、SwiftUIではそのようなことはできません。

キュー (Queue)

SwiftUIではGCD(Grand Central Dispatch)というキューの仕組みがあります。
SwiftUIのアプリ内で行われる処理について適切にキューイングを行う必要があるようです。
これを適切に使わずに全て実行してしまうと、メインスレッドで直列で処理が行われることになってしまい、アプリが動かなくなったり落ちたりしてしまいます。
UIの更新に関してはメインスレッドで行わないといけないというような決まりがありますが、その他のタスクはメインスレッド以外で並列で処理するなど、キュー管理の理解が必要になります。
これはTauriなどのようなフレームワークでアプリ作成する場合とは違って考慮が必要な部分になってくると思います。

こちらはGCDなどと調べると詳しく解説されたページがたくさん出てきます。

データの永続化

SwiftUIで外部DBなどに依存させずスタンドアロンなアプリを作る場合、CoreDataという仕組みを使うことになります。
Webアプリ開発で使うMySQLSQLiteを想定していると、使うまでに必要な前提知識を理解するのが難しい印象です。

ただ最近SwiftDataというものが使えるようになってようで、CoreDataよりも簡単に扱えるようになっていました。
CoreDataは利用するハードルが初心者にとっては高い印象でしたので、SwiftDataは初心者にとってもアプリ開発のハードルを下げてくれそうです。

何を作ったのか

最後に何を作ったのか紹介します。

私はChatGPTに質問を投げる機会が結構あります。
GitHub上で検索してみると素晴らしいChatGPTのデスクトップアプリケーションはいくつも存在しています。
ただ、どのアプリも基本的にはチャットでの対話型のUIとなっています。
しかし、例えばある言葉の定義を知りたい時に、いちいちチャット対話画面を毎回開くというのは少々めんどうくさいです。
ランチャーなどでテキストを入力してそれに回答を受け取れればそれが一番利便性が高いと思いました。

そこでSwiftUIでChatGPTへメッセージを送信し、その回答をstream方式(ChatGPTが回答を細かく返してくる方式)のレスポンスで受け取りつつ動的にビューを画面上に作って表示するアプリを作りました。

そして今回はURLスキームを使ってopen quickgpt://chat/"hello world"(quickgptはアプリ名)でChatGPTにメッセージ送信できるようにすることで、自由に呼び出し元を選べるようにしました。
私はAlfredというランチャーアプリのWorkflowという機能で上記コマンドを加工して、ランチャーアプリからメッセージを送れるようにして使っています。

qiita.gif

工夫した点

  • steam方式に対応させて、レスポンスを受け取るたびにビューのテキストを更新してリアルタイム性を高くした
  • 回答を表示するビューを好きな位置に移動できるようにした
  • ビューの移動位置を保持するようにして、ビューの位置に一貫性を持たせた
  • マルチモニターに対応している(はず)
  • ステータスバーを活用して、アプリのビュー自体に無駄なボタンを設置しないようにした
  • アプリのURLスキームを使ってChatGPTにメッセージを送れるようにし、呼び出し元を縛ることのないアプリにした

TODO

  • 回答が返ってきた時にmacOSのスピーチ機能で読み上げできるようにしたかったが、macOSのバージョンアップデートで動かなくなってしまったので修正が必要

終わり

今回SwiftUIでmacOSアプリを作ってみましたが、やはりネイティヴな操作を行うことができるため、普段の手元での操作やタスクを効率化するには非常にパワフルだと思いました。
ただしWebアプリ開発者視点からすると、やはりWebアプリ開発とは当然ですが事情が全然違うところは多く、学習コストは高めだと感じました。

11
2
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
11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?