この記事は DeNA 21 新卒 Advent Calendar 2020 の13日目の記事です。
まえがき
個人開発は、自分の好きなことを好きなようにできる反面、アイディア、設計、実装、運用、サポートをすべて自分自身で行う必要があります。この記事はとある個人開発者が1つの iOS App を開発するときに経験した事柄を綴った長編大作(?)です。
こんなひとに読んでほしい
- 個人開発がどのようなものかを知りたい方
- iOS App の開発に興味がある方
- (少しの)iOS App 開発あるあるを読みたい方
とても長いのでお品書きを参考に、気になったセクションだけを読んでいただくのも良いかと思います。
お品書き
※リンクをクリックで各セクションにジャンプできます。
- 私は誰
- それは突然やってきた(アイディアが実現可能になった)
- 開発を始める前に
- 動作確認のために車で 130km 移動
- ひたすら開発を続けていく
- App Store でリリース、コア部を OSS として公開する
- リリース後に起きたこと
- 個人開発の陰と陽【ユーザーからの声がダイレクトに届く】
- 世の中の需要に合わせてアップデートしたり、UI デザインについて考えたり
- モチベーションの維持は好きから
私は誰
小中学生のころは「Word でつくれる Web サイト作成!」みたいな本を見ながら遊んでいました。コピペで動く JavaScript のアクセスカウンターなどで HTML、CSS、JavaScript の存在は認識していましたが、自分で書いてみることはしませんでした。
2014年の Apple WWDC14 で Swift が発表されたことをきっかけに、プログラミングをはじめました。そのあと、高専の授業で C言語 の授業がスタートしたので、母国語は Swift です。
自分専用の RSS リーダーだったり Twitter クライアントだったりを作っては消しながら、Swift と iOS 開発について独学で勉強してきました。
2019年の Apple WWDC19 の後、はじめて個人名で iOS App をリリースしようと決め、2019年9月の iOS 13 の一般リリースの時期に Japan NFC Reader を App Store (iOS, watchOS) にて公開しました。
それは突然やってきた(アイディアが実現可能になった)
iPhone に入れられない電子マネー、カードのまま使う
今日普及している電子マネー、カードもしくはスマートフォンなどを「ピッ」とかざすだけで列車に乗ったりモノを買ったりできるのはとても便利です。電子マネー機能をスマートフォンに追加して使うこともできますが、iPhone の場合は Apple Pay に対応する必要があるなどの理由から、よく使う電子マネーを iPhone に入れることができず、物理カードを使っているユーザーも多いかと思います。
このカードにいくら入ってるっけ…
事前にお金をチャージして使う必要があるプリペイド型の電子マネーは、そのカードに今いくらの残高が残っているのか知りたい場面があるでしょう。そこで便利なのが残高確認機能をもつアプリケーションです。Windows PC、Mac、Android 端末には電子マネーサービス事業者公式、もしくは有志作成のアプリケーションがありますが、iPhone にはそのどちらも存在していませんでした。
「ピッ」を実現する NFC (FeliCa)
物理的な金銭が授受されているわけでもなく、まるで魔法のように「ピッ」だけで決済等が行えるシステムに、私は小学生のころから強い興味がありました。
この「ピッ」を実現している技術は NFC1 と呼ばれます。日本でメジャーなプリペイド型電子マネーはこの NFC のうちの FeliCa2 を用いています。この NFC 機能を提供する API が iOS では公開されていなかったため、そもそも開発することができなかったのです。
iOS 13 でついに API 解放
しかし、WWDC19 で発表された iOS 13 の新機能として、NFC の API が解放されることが発表されます。3
お、iOS 13 の Core NFC、
— treastrain / Tanaka.R (@treastrain) June 4, 2019
ついに FeliCa、MIFARE タグの読み取りができるようになるみたい!!!#WWDC19 #iOS13 #NFC #FeliCa pic.twitter.com/C1UtAV2byr
小さい頃から抱いていた興味と、Apple 信者になってしまっている自分、そして用意されたフレームワーク。これは開発するしかないと発起し、すぐに調査を始めました。
開発を始める前に
サンプルコードなんてどこにもない
いくら興味があるとはいえ、実際に NFC(FeliCa) がどのように通信を行うかについて、この時点で私は1ミリも知りませんでした。Apple のドキュメントには「No overview available.」が並んでおり、頼りになるのは WWDC のセッションのビデオ4くらいしかありません。
セッションのビデオを観て、メソッド名から機能を予測し、使うであろうものをメモするところから始まりましたが…。ビデオの中で出てきたのは…
You can go ahead and refer to Sony's FeliCa command specification for more details.
…… んんん… 確かに FeliCa はソニーの技術ですから、Apple としては「メソッドは用意したから、あとは自分たちで調べてみてね」ということでしょう。やはり自分で NFC(FeliCa) について学ぶ必要がありそうです。
仕様をひたすら読み込む
Apple の言う通り、ソニーが公開している FeliCa の技術情報5についてひたすら読み込みました。これに関しては日本企業ということもあって日本語の資料だったため、読むだけであれば不自由なく行うことができました。
また、Windows、Android で NFC に関連する OSS のコードもたくさん読みました。と言っても、母国語の Swift しか理解できない状態だったので、C# や Java を雰囲気だけで読んでいきました。
iOS 独自の仕様(?)に気づく
FeliCa について段々と理解してきたところで、いよいよ Swift による iOS App の開発を始めます。まずは単純に電子マネーカードを読み取るだけの機能を実装しました。Qiita に記事も残しています6。
開発を進めていく中で、期待した通りに動作しないパターンが出てきました。種類の異なるカードを iPhone にかざしたとき、一方のカードを検知するまでにかなりの時間を要したり、そもそもソニーが公開している FeliCa の技術情報5通りに動作しないメソッドの存在がわかってきたのです789。
この iOS での独自仕様とでも言うべき動作について理解しながら、「iOS での FeliCa による通信の取り扱い方」を自分の中でまとめていくことに骨が折れました。とくに、iOS 13 はこの時点で beta であるため、この動作がバグである可能性も疑う必要がありました。
動作確認のために車で 130km 移動
動作確認は実機で行うしかない
iOS App の開発では開発中の動作確認をまず Simulator で行うかと思いますが、今回の開発は NFC を取り扱う性質上、iPhone 実機でしか動作確認を行うことができません10。
そして、電子マネー事業者以外の開発者がカードにできることは、「「「一般公開されている技術情報5」」」からカードを「「「読み取るだけ」」」です。カードの情報を書き換えたりすることはできない仕組みになっています。カードの情報について理解するには、そのカードの使用前と使用後のデータの差分を取り、どのように変化したかを調べる必要がありました。
そのため、まず iPhone を使ってカードのデータを確認し、コンビニ等で買い物をしてからもう一度カードのデータを確認する… といったことを繰り返していました。
私のいる地域では紙のきっぷしか使えない
さて、スーパー、コンビニで使える電子マネーの調査は自分のいる地域で何とか行えました…… が、交通系ICについての動作確認を行わないわけにはいきません。しかし、この地域では交通系ICに非対応………。こうなったらこうするしかありません。
札幌へGO!!!11
*※スクリーンショットは札幌からの帰り道*カードを「ピッ」として改札内に入ったら Mac を開いて iPhone でカードを読み取りデータを確認。1駅乗って改札を出たらまた Mac を開いて iPhone でカードを読み取りデータを確認。もう一度同じ駅で改札に入って Mac を開いて iPhone で……。地道に動作確認を行いました…。
TestFlight で交通系ICカードが使えるエリアにいる友人を頼る… ことも今なら可能ですが、まだこの時 iOS 13 は beta であり、自分が動く以外に方法はありませんでした。
ひたすら開発を続けていく
どこまでの機能を用意するか
あくまで個人開発、自分の無理のない範囲で機能を実装、それで十分だと言ってくださるユーザー数(100人くらい)を想定して開発を行っていました。無理のない範囲でかつ、自分が「実装してみたい」と思った機能です。
- カードの読み取り
- カードに記録されている残高、利用履歴の表示
- これまでに読み取ったカードの表示
- iCloud 同期により他のデバイスでも表示
- 当初は Apple Watch の文字盤に iPhone で読み取った時点の残高を表示させようとしていて、データの同期に iCloud を使おうと考えていた
- iCloud 同期により他のデバイスでも表示
- カードに好きな色や名前をつけることで管理を容易に
- アクセシビリティへの対応
- VoiceOver
- Dynamic Type(文字サイス変更対応)
- (厳密な調査はしていないものの)色覚特性
もちろん、上に挙げた以外で予定していた機能もいくつかありますが、実装の複雑さや冷静に考えたときに「その機能… いる……?」と思ったものに関しては実装を取りやめました。
アセットはどうやって作るか
App をリッチにするにはアセットの用意が不可欠です。この iOS 13 のタイミングではちょうど Apple による SF Symbols の提供がスタートしましたので、基本的にはそれを利用しました。
SF Symbols で用意されていないようなアセットについて、私は Keynote を使って作成していました。いわゆるパワポ作図12です。スライドのサイズを正方形に変更し、「図形」を組み合わせてパスを結合して… かなり便利に使うことができます。
その他、iOS App 開発あるあるでハマる
だんだん iOS 13 の一般リリースが近づいてきて、さすがに同じ時期に App Store でリリースしたいと考えながら開発をしていると、本質ではないところで思わぬ足止めを食らうことが多くなりました。ここではその一例を挙げておきます。
- iOS beta の不具合で NFC 関連機能が使えなくなる
- 新しい beta にアップデートしてしまった
- beta なので何も言えないが、この期間は開発がストップしてしまう
- 複数の iPhone に違う beta を入れてちゃんと検証しよう
- (↑当時は iPhone X 1台(しかもメイン端末)で戦っていた)
- 忘れたころに現れる
signal SIGABRT
- 疲れた状態でうっかりどれかの
.xib
や.storyboard
の接続を変更してしまい、ファイルを周回することになる - Breakpoint を張ろう
- 疲れた状態でうっかりどれかの
- Xcode と iPhone 実機が繋がらなくなる
"デバイス名" is not available. please reconnect the device.
- デバイスの再登録や Xcode の終了、iPhone や Mac の再起動を試して、それでも解決しなければその日はもう寝る
- 新しい Xcode beta の
.xip
が Mac の空き容量不足で展開できない- そもそも Xcode 自体、サイズが大きい
- 新しい各 OS beta のコンポーネントのダウンロード、プロジェクトのビルド、アーカイブを繰り返すことで気づかないうちに Mac の容量をどんどん消費していく
- ちゃんと
.xip
の展開のために容量を空けたはずなのに展開できない - Mac の再起動や Mac に残っている Time Machine のキャッシュファイルの削除を試そう
App Store でリリース、コア部を OSS として公開する
紆余曲折がありながらも、2019年9月22日、無事に App Store でアプリを公開することができました。また、Core NFC を使ったカードの読み取りに関する部分は OSS13 として公開しました。
私としては Swift についてさまざまな OSS から学んできたという経緯もあったため、少しでも貢献できればという思いで OSS としての公開に踏み切ったのですが、これが結構よかったようです。自分の書いたコードが公開されることで、「もう作り続けるしかない!」という気になった他、Core NFC を活用したコードはこれまであまり公開されているものがなかったため、さまざまな方面からアクセスされました14。
リリース後に起きたこと
Web メディアなどで紹介され始める
2019年6月の WWDC19 での iOS 13 の発表から 9月のリリースまでの間に、大手の Web メディアにて「iOS 13 では電子マネーを読み取れるようになる」という記事が公開されており、この機能に関する関心は比較的高いものとなっていました。
そして iOS 13 の一般リリース後、大小さまざまな Web メディアがこの「電子マネーの残高確認アプリ」を複数取り上げました。
Firestore が上限に達する
この Web メディアによる取り上げは非常に強力なものでした。Spark プランで使用していた Firebase Firestore が上限に達し15、Analytics のグラフがものすごい右肩上がりを示しました。これにより、「100ダウンロードくらいされればいいかな」という考えを改めなければならない事態になっていきました……。
インターネットテレビ・書籍に載る
ここまで来ると「あの Web サイトで紹介されていた」「Twitter で誰々さんがツイートしていた」といった情報をすべてキャッチすることができなくなってきます。私が一番驚いたのは、インターネットテレビで突然紹介されていたことでした。
え?
— treastrain / Tanaka.R (@treastrain) October 1, 2019
は?
ええ??
なんか @AbemaTV で紹介されてるんだけど @JapanNFCReader pic.twitter.com/WfqEar5fwt
私はテレビを設置していないので、お昼ごはんを食べながらインターネットテレビを観ていたら突然聞き覚えのあるアプリ名が…「いやそれ私のアプリやないかい!」さすがにこれには興奮を隠せませんでした。
また、いくつかの書籍にも iOS 13 での新機能として取り上げられました。インターネットテレビも書籍も掲載前に連絡が来る… といったことはなかったので、完全に放映されてから、もしくは書店で立ち読みしていたら「!?」で知りました。
とりあえず買ってきたよね pic.twitter.com/TP2TfaPB6f
— treastrain / Tanaka.R (@treastrain) November 4, 2019
個人開発の陰と陽【ユーザーからの声がダイレクトに届く】
このような状況になると、アプリに対するポジティブ、ネガティブな声が App Store のレビュー、Twitter、はてブや Web メディアのコメントで見られるようになりました。個人開発ではそれらが自分に、ダイレクトに刺さります。よろこびの声は「作ってよかった…」と安心させてくれ、改善すべき点の鋭い指摘は「ありがとうございます… 仰るとおりです……」とアプリのアップデートのきっかけにもなりました。悲しい声は… 悲しい気持ちになりました………。
また OSS に関しても、コントリビュートをいただいたり、実際のアプリ開発で利用されたりといったことを聞いたりしたときは「公開してよかった」「もっとよいものになるようにアップデートしていきたい」という気持ちになりました。反対に、ライセンス違反が疑われる状態で利用されているアプリを見つけてしまったときは、とてもとてもとても悲しい気持ちになりました。
世の中の需要に合わせてアップデートしたり、UI デザインについて考えたり
不思議なめぐり合わせによって多くのユーザーに使ってもらうこととなったアプリ、「電子マネーの残高を確認する」という機能の特性から、「誰でも使えるアプリ」を目指して新しい機能を追加したり、UI デザインについて考えたりしています。
モチベーションの維持は 好き から
以上、私の個人開発体験記でした。開発の始めからリリースまでを疑似体験できるように書いたつもりでしたが、いかがだったでしょうか。
すべての動機は「好き」「やってみたい」という好奇心から生まれてくるものでした。まだ眠っているアイディアを世に送り出すことができるように、これからも個人開発を続けていきたいと思います。
お知らせ
こちら、DeNA 21 新卒 Advent Calendar 2020 からのお知らせです。
この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ LGTM、Twitter や Facebook、はてなブックマークにてコメントをお願いします!
また DeNA 公式 Twitter アカウント @DeNAxTech では、 Blog 記事だけでなく色々な勉強会での登壇資料も発信しています。ぜひフォローしてください!
謝辞
この記事は @terubooon による 新規Webサービスを独りで開発・運用する際に立ちはだかった壁とそれを乗り越えた方法まとめ【個人開発】 にインスパイアされて執筆しました。
-
Near Field Communication。近距離無線通信。 ↩
-
FeliCa。ソニーの登録商標。Suica、PASMO などの交通系ICカードや楽天Edy、nanaco、WAON などの電子マネーカードはこれを用いている。 ↩
-
iOS で NFC を取り扱う際に使用する Core NFC フレームワークは iOS 11 以降で利用可能でしたが、その時点で解放されていた API でできることはかなり少なく(NDEF の読み書き程度。Chrome 81 の Web NFC くらいの機能しかない)、「電子マネー残高の読み取り」に必要な部分までは解放されていませんでした。 ↩
-
Core NFC Enhancements (日本語名: Core NFCのエンハンスメント) - WWDC 2019 - Videos - Apple Developer ↩
-
もちろん、カードの読み取り機能以外は Simulator で動作確認できますが、どの機能もカード読み取りありきの動作のため、Simulator でできることは UI のレイアウト確認くらいです。 ↩
-
自分のいる地域からもっとも近い交通系ICのエリアは苫小牧でしたが、列車の本数を考慮し、基本的には新千歳空港駅や札幌エリアに出向いていました。札幌まで向かったのは札幌市営地下鉄のカードを入手するためです。 ↩
-
PowerPoint も Mac に入っていますが、学校からの Office 365 ライセンスのため使用しませんでした。 ↩
-
treastrain/TRETJapanNFCReader - GitHub。こちらの OSS は App Store リリースの少し前から public にしていました。 ↩
-
GitHub の Insights にある Traffic の情報の中の "Referring sites" から。 ↩
-
もともとオフラインで動作するように開発していたため、Firestore にアクセスできなくなってもアプリの動作には影響しませんでした。 ↩