個人開発アプリが「月間ベストアプリ」に選ばれApp Storeで紹介されるまで
2021年9月20日、iOS 15のリリースに合わせてSvadilfariというアプリをリリースしました。iOS 15で追加されたSafari機能拡張の仕組みを利用して、Safariにジェスチャー操作を追加するアプリです。
個人で2ヶ月ほどかけて制作したアプリなのですが、想定より多くの方にダウンロードしていただき、「ウェブ閲覧を快適に」「2021年9月の ベストAppとゲーム」の2つのApp Storeストーリーで特集していただきました。また、アプリ単体としてもApp StoreのAppタブで紹介していただきました。
技術的な観点やAppleとのコミュニケーションは別の記事にまとめることにして、この記事ではプロジェクトに取り組んだきっかけや、開発において大切にしたことについて書き留めてみます。
リリースまで
まず、アイデアの発想から現在に至るまでの流れをまとめてみます。
6月中旬: WWDC 21でSafari機能拡張について知る
本当の最初のきっかけは、WWDC 21でした。Keynoteにて、iOS/iPadOSのSafariに機能拡張が追加されることを知ります。
私は普段Webフロントエンドを中心に開発を行っており、iOSアプリ開発も趣味で行っています。Safari機能拡張は私が経験のある2つの領域を組み合わせることができると考え、なにか作れないか考えるようになりました。
この段階でベッドの中からSafari機能拡張に関するセッションを視聴し、新しく追加されるAPIで
- WebExtensions APIが(一部制約はあるものの)動作するようになる
- App Extensionとして扱われ、Swiftと通信ができる
といった解像度でAPIの全体像を掴みました。
7月初旬: アプリの着想を得る
大学が夏休みとなり、ある程度時間があったのでベータのiOS 15を開発用の端末にインストールして遊んでいました。
iOS 15では、Safariのデザインが改善され、賛否両論あるものの片手でも操作しやすいUIになりました。一方で、「タブを閉じる」「新しいタブを開く」といった基本的な操作であっても複数回のタップが必要になるのが残念に感じました。
ここで思い出したのが、Sleipnizer for Safari というJailbreak Tweakです。
ジェスチャー機能のブラウザというとフェンリル社のSleipnirが有名で、アプリ版も開発されていますが、同じ機能をJailbreak TweakとしてSafariに導入するのがSleipnizerです。
iPhoneをJailbreakして使っているときに愛用しており、これと同じ機能をSafari機能拡張として再現できないか考えました。
機能拡張からはWebページ上で任意のJavaScriptを実行できるため、そこでジェスチャーを認識できれば、様々な操作ができるはずです。この段階では、小さなプロジェクトを作って実現可能性を確かめていました。
7月中旬: アプリ名称の検討
私は形から入るタイプなので、まずアプリ名を検討し始めました。
Sleipnir, Sleipnizerに強く影響を受けているので、同じ北欧神話に出てくる馬で...と考えて調べると、Sleipnirの父親にあたるSvadilfariがヒットしました。
正直なところ、Sleipnirの父親の名前を使うのは憚られたのですが、Svadilfariの中にはSafariという文字が含まれていることから「これしかない!」と、この名前に決めました。App Storeを検索して同じ名前のアプリがないことだけは確認しています。
7月下旬: デザイン作成
暇な時間を使ってアプリのデザインをはじめました。デザインとはいっても、UIはiOS標準のものを使うつもりだったので、パーツの配置がメインのワイヤーフレームに近いものです。
最近の個人開発では、デザインを先に作ってから実装をすることを心がけています。
理由としては
- 実装する機能を明確にすることができる
- アプリの全体像が開発初期からある程度見通せるため、適切な粒度でコードを設計できる(特にUIコンポーネント)
- 「頑張って実装したけど微妙だった」を防げる
- 「このUIにしたいけど実装が大変すぎるから妥協しちゃおう」も防げる
などが挙げられます。
特に3は大きく、実装しながらUIを作っていると、「動作するUIを作ること」がゴールとなってしまい、実装な複雑なものはデザインを変更することで達成しようとしてしまいます。デザインを先に作ることで、実装フェーズでのゴールが「デザインを実装すること」になり、多少複雑な実装があっても頑張って実装しようという気持ちになれます。
似た理由で1も大切です。アプリを作りながら機能を実装していくと、「動作するアプリを作ること」がゴールになってしまい、本当に最低限の機能だけで満足してしまいがちです。特に今回のアプリでは、最初のバージョンから実用に耐えうるものを作りたいと考えていたため、「カスタムジェスチャー」「除外リスト」など、必ずしも必要ではない機能の開発にも力を入れました。
AppleのHuman Interface Guidelineを読み込み、またiOS標準アプリのUIを研究しながら、デザインを仕上げていきました。
デザインには、Whimsicalを使いました。FigmaやSketch、XDなどのツールと比べて直感的に操作することができ、エンジニアでもストレスなく使うことができるのが魅力です。
同時期にアイコンも作成しました。馬のフリー素材とiOSアプリアイコンのFigmaテンプレートを組み合わせて自力で作成しました。
8月: 実装
8月に入ると、使用する技術を選定し、実装を開始しました。
技術選定
Web技術を使った機能拡張の部分に関しては、私がトレンドを追えていることもあり、特に悩むことなく以下の構成に決まりました。
- 言語: TypeScript
- トランスパイラ: esbuild + tscによる型チェック
- UIライブラリ: React
機能拡張にはライブリロードなどが一般的ではないため、単純にTypeScriptをJavaScriptに変換するだけのバンドラが必要でした。esbuildとswcどちらでもよかったのですが、個人的な好みでesbuildを採用しました。
ネイティブアプリの部分に関しては、以下の技術を使うこととしました。
- 言語: Swift
- UI: SwiftUI
- データストア: CoreData, UserDefaults
SwiftUI, CoreDataに関しては知見がほぼ0の状態でしたが、2021年に新規でアプリを開発するには必須と考え、ある程度の学習コストを払う覚悟で採用しました。
加えて、ネイティブアプリと機能拡張の間でデータをやり取りする仕組みが必要でした。JSONをやり取りできるのですが、任意のデータ構造が送れてしまうのは怖いので、TypeScriptとSwiftで利用できるスキーマのようなものを探しました。Protocol Buffersも面白そうではあったのですが、JS実装が不安だったのでJSON SchemaとQuickTypeの組み合わせに決定しました。
学習・実装
早速実装に取り掛かったのですが、ネイティブアプリの部分はとにかく分からないことが多く、1つの機能を実装するのに2、3日の学習が必要なこともありました。
SwiftUIに関しては、Apple公式のチュートリアルを一通りこなし、その後は必要に応じて検索しながら進めました。
SwiftUIは、宣言的UIというReactとの共通点があり、またレイアウトの仕組みもFlexboxと似ているため、比較的スムーズに習得できました。プロパティラッパー各種が一番難しかったですが、定期的に SwiftUI Property Wrappers を開きながら進めました。
少し余談ですが、SwiftUIに関してはKarin PraterさんのYouTubeチャンネルがオススメです。
YouTubeのvideoIDが不正です
物理学のPh.D.を取得されているアカデミア出身の方で、大学の授業のようなフォーマットでSwiftUIのチュートリアルをYouTubeに投稿されています。万人受けするコンテンツではない気がしていますが、「やってみた」だけの動画でなく、コードの裏側の思想なども解説されていて勉強になります。
開発を通して苦労したのがCoreDataでした。インターネット上に様々なチュートリアルがあるものの、SwiftUIと組み合わせて使っている情報が少なく、仕組みを十分理解していないこともあって苦労しました。
また、CoreDataをアプリ本体とApp Extensionと同期するPersistent History Trackingという仕組みがあるのですが、これを動作させることが非常に大変でした。
とにかく情報が少なく、限られているブログ記事や公式ドキュメント、GitHubに公開されている当該APIを利用しているプロジェクトを参考に試行錯誤を続け、なんとか動作させることができました。
8月の下旬には、ほとんどの機能が一通り動作するようになっていました。
9月中旬まで: アプリの完成・リリース
9月上旬に引っ越しをしたこともあり、あまり開発時間が取れませんでしたが、細かい機能改善とチュートリアルの実装を行いました。
業務でも同様ですが、特に個人開発だと機能開発で燃え尽きてしまい、チュートリアルやオンボーディングが疎かになってしまうことはないでしょうか。
YouTubeのvideoIDが不正です
大学の授業で観たこの動画が力になって、チュートリアルもある程度のクオリティのものを作成することができました。
動画では、WufooというGoogleフォームのようなサービスを創業したKevin Hale氏が、新規顧客の獲得はデートのようなものだとした上で、第一印象が非常に大切であるとしています。その上で、Webサービスやアプリにおける第一印象は登録やログイン、最初に行う操作であり、そこにサプライズを隠すことでユーザーといい関係を気づくことができると言っています。
Svailfariのチュートリアルに驚く要素はないかもしれませんが、機能拡張を有効化する手順をできるだけ分かりやすく説明した上で、チェッカーへのリンクを設置しています。これによって、機能拡張が有効になったことを簡単に確認でき、サポートでも活用できています。
その他にも、Svadilfariは日本語と英語をサポートしています。開発は英語で行っていたため、日本語への翻訳もこのタイミングで行いました。
Webサイトや問い合わせフォーム、プライバシーポリシーなど必要なものを準備し、App Storeに提出しました。
一度「アプリが動作しない」とレジェクトされてしまったのですが、動画を添付して再審査に出したところ、iOS 15のリリース数時間前に審査を通過しました。
iOS 15のリリースを待ってApp Store Connectからアプリを公開し、告知ツイートをしました。
どうしてもiOS 15のリリースに間に合わせたかったので、最後の2日はほぼ徹夜で作業をしていたのを覚えています。
9月下旬: App Storeストーリー
普段つまらないツイートしかしていないので発信力が絶望的なのですが、前述のツイートを沢山の方にリツイートいただきました。
リリース後、1日ほどでYouTuberであるマメさんに動画でご紹介いただき、ダウンロード数が増え始めます。
皆さまのおかげで、ピーク時には1Passwordを抜いて無料Safari機能拡張ランキング3位になりました。
その後、Gizmodoをはじめとして、様々なメディアにも掲載していただきました。
こうした結果、iOS 15のリリース直後に追加された「ウェブ閲覧を快適に」というApp StoreストーリーでSvadilfariが紹介されます。
そしておよそ一週間後、「2021年9月の ベストAppとゲーム」に掲載されました。
ポケモンユナイトやファイナルファンタジーと同じ並びに自分のアプリがあるのは本当に感動でした。
ちなみにですが、App Storeストーリーへの掲載に関してAppleから特に連絡はなく、ベストAppに関しては上のツイートで初めて知りました(笑)
10月: Appタブへの掲載
ベストAppの選出と同日に、 "Your app, Svadilfari, may be featured on the App Store." と題されたメールが届きました。要約すると
- SvadilfariがApp Storeでフィーチャーされるかもしれない
- 追加でストア用の画像(Promotional Artwork)を提出する必要がある
- 期限は1週間
とのことで、Promotional Artwork用のガイドラインのリンクも送られてきました。
"may" というのが重要で、クオリティの低い画像を提出すると掲載してもらえない可能性もありました。これを自分一人で作成するのは無理と判断し、プライベートでも仲良くしている @yotaszk にヘルプを依頼したところ、忙しい中、快く引き受けてくれました。
連日Zoomでデザインを話し合い、期限内に画像を提出しました。そこから約1週間後、実際にAppタブにてSvadilfariが紹介されました。
Promotional Artworkの作成に関しては、別の機会にまとめようと思います。
Key Takeaways
以上が、着想からリリース後までの一連の流れになります。ここから、Svadilfariのこれまでの開発を通して学んだことをまとめてみます。
最新技術のキャッチアップを怠らない
このアプリの開発の最初のきっかけは、WWDCのKeynoteを観たことでした。特にスマホアプリの市場は既に多くのアプリが公開されており、アイデアだけで新しく広く使われるものを作るのは難しいと感じています。その点、iOSのアップデートで追加される新技術・APIを利用することは大きな差別化の要因となり得ます。
iOS 15のリリースから1ヶ月以上が経ちますが、広告ブロックやパスワードマネージャー以外のSafari機能拡張の数は限られています。App Storeで特集していただけたのも、Appleとして普及させたい新技術を利用していたことがかなり大きいと思います。
iOS 15では同時にSharePlayやPicture in PictureのCustom Source Viewなど、アイデア次第で様々なことができそうなAPIが追加されていますが、これらも広く活用されているとは思えません。
常に最新技術の動向を追い、アイデアを探すことがアプリのユニークさ、品質の高さに繋がるのではないでしょうか。
妥協しない技術選定
今回の開発では、私が触ったことのなかった技術も含めて、「最高のプロダクトを作るために何を採用するべきか」という観点で技術選定を行いました。
SwiftUIの代わりに、UIKitをやReact Nativeなど経験のあるUIフレームワークを採用すれば、学習にかかる時間を大幅に減らすことができたと思います。
プロダクトコード以外にも、Web拡張部分のStorybookやアプリ部分のXCUITestなど、プロダクト本体に関わらない部分を妥協すれば、開発にかかる時間を削減できたでしょう。
Svadilfariが多くの方に使っていただけた理由の一つは、使っていて違和感のないアプリにできたからだと思っています。そのために、iOSの世界観に忠実なSwiftUIや、非機能要件に関連する技術は必要不可欠でした。
自らの知識などを理由に妥協することなく、プロダクトのことを第一に考えた技術選定が、最終的な品質に貢献したと考えています。
妥協しない機能開発
デザイン作成の項でも触れましたが、チュートリアルや必須ではない機能、細かいデザインについても、品質を妥協せず作り上げたつもりです。
特に個人開発では、「リリース」が一つの明確なゴールとなるため、そのために品質や機能がおざなりになりがちだと思います。これまで自分が作ってきたプロダクトにおいても、コア機能はユニークなのにチュートリアルやその他の機能の作り込みが甘く、結果的に使ってもらえないことがありました。
「有効化できない」といった問い合わせも0件ではありませんでしたが、多くの方に導入のハードルをクリアしてジェスチャーを試していただけたのが、Svadilfariからの学びだなと思っています。
国際化に関しても、海外の方からもフィードバックや機能リクエストをいただいているため、やってよかったと思っています。
友達を作る
「個人開発」といっても、完全に一人で行うことは少ないと思います。Svadilfariの場合は、アプリの公開までは自力でたどり着きましたが、そこからTwitterやブログでの拡散や、App Storeのプロモーションアートワークの作成に知り合いを頼ることになりました。
私はどちらかというと内向きな人間なのですが、エンジニアに限らず、デザイナーやブロガーなど、関連する業種の人とのネットワークは大切にしたいと改めて感じました。
さいごに
以上、長くなってしまいましたが、Svadilfariの企画から現在に至るまでの出来事と、それらを私が通して感じたことをまとめてみました。
その自由度の裏返しで、個人開発には個人開発ならではの難しさがあると思いますが、この記事が少しでもどなたかの参考になれば幸いです。
Svadilfariは、App Storeから無料でダウンロードできます。
また、ソースはすべてGitHubで公開しています。よろしければスターもいただけるととても嬉しいです...⭐⭐⭐ コードはあまりキレイではないかもしれないですが、PRなどもお待ちしております!
Discussion