旧仮名キーボード開発記#10|開発の変遷(後篇)
前回の続きです。
前回:
***
令和5年春(開発再開)
この時点ですでに名詞さえ整えばすぐにでもリリースできる状態だったのですが、あまりに作業が退屈なので何ヶ月も放置していました。
そこで、とりあえずアプリとしてまとめあげることを重視し、あえて開発期間に締切を設けることにしました。もともと個人企画なので締切を設ける必要はないのですが、名詞の数には限りがないことを考慮すると、完成し次第リリースするという計画よりも、締切までに一応形にするという計画のほうが現実的だと判断したからです。
ここでリリース日を同年11月16日に決定し、作業を本格的に再開しました。しかし、名詞は他の品詞と異なり、典拠としている中型辞書に収録されていないものも多く、非常に苦労していました。
ある日、たしか「反骨精神」の「反骨」という単語は「叛骨」「反骨」のどちらが主流だったのかを調べようとしたときのことですが、数ヶ月前ぶりに国会図書館デジタルコレクションを開いて非常に驚きました。以前は使い勝手が悪く、読み込みも遅かった操作画面が、いつの間にか非常に使いやすくなっており、読み込みも速くなっていたのです。さらに、書籍内の文字を全文検索できる機能まで付いていました。全文検索機能は、画像内の文字を高精度に抽出してくれているだけでなく、新字と旧字の揺れまで吸収してくれる優れもので、この機能が付いてくれたおかげで、仮名遣いの調査効率が格段に上がりました。
令和5年夏
ここまでで、NAIST辞書に収録されていた一般名詞についてはすべて書換作業が完成しました。
しかし、まだ固有名詞が残っています。
現代で使われる固有名詞の大半は戦後に誕生した言葉であり、仮名遣いの分からないものもかなりあります(特に商品名や会社名)。作業量的にリリース日に間に合わないため、9月末までに完成したところをもってリリース版とする方針で進めることにしました。
ここで、もともとNAIST辞書に含まれていた固有名詞はすべて無視し、苗字、地名、駅名、路線名など伝統的な語彙が多いと考えられる分野を優先し、ゼロから収録していくことにしました。
なお、地名の仮名遣いについては、調査に手間取ったものが多かったです。たとえば「三重県いなべ市」の「いなべ」は漢字でどう書くのかという調査から始まり、漢字表記が「員弁」と分かったあとも、その「弁」の旧字は「辨」なのか「瓣」なのか「辯」なのか、また「い」の読みは「員」の字音を採って「ゐ」となるのか、それとも別に語源があって「い」のままなのかなど、1つの地名について調べるのでも大変な手間がかかります。
一応、国会図書館デジタルコレクションの『大日本地名辞書(上巻・中巻・下巻・続編)』を典拠とし、現行の市区町村以上の日本地名についてはほとんど片付きましたが、非常に時間がかかりました。
また、アイヌ語由来の地名には悩みました。たとえば、「夕張」は「ゆうばり」なのか「ゆふばり」なのか、「遠軽」は「えんがる」なのか「ゑんがる」なのか、「音威子府」は「おといねっぷ」なのか「おとゐねっぷ」といった問題です。北海道は日本語風に聞こえる地名も大半はアイヌ語由来なので、「夕(ゆふ)」をそのまま「ゆふ」としてよいのかどうかという一見簡単そうに見える問題についてすら、一々個別に考える必要があります。
典拠とした地名辞書を見ると、大半のアイヌ語地名は漢字の仮名遣いを優先しているように見えるのですが、そうでない場合もあったり、目次と見出し語とで仮名遣いが食い違っていたり、そもそも仮名遣いの正確性に無頓着な雰囲気すら感じられます(出版年が古すぎるからかもしれません)。もう少し精密な研究が必要だと思ったのですが、追究していると時間がなくなるので、とりあえず典拠とした辞書が見出しとして掲げている仮名遣いを採ることにしました。
令和5年10月(謎の不具合)
予定どおり、固有名詞の作業は9月末で切り上げました。
10月からは、細かい設定機能、UI、パフォーマンス、変換精度の改善に着手したのですが、ある時期からアプリが突然落ちるようになりました。
最初はメモリのアクセスエラーだと思い、再現方法を調査していましたが、一向に発生条件が特定できません。どうやらGoogle Mapで開くと落ちやすい、変換候補が大量になると落ちやすい、何度も高速で開いたり閉じたりしていると落ちやすいという傾向だけは分かったのですが、謎の不具合として何日も原因が分からないままでした。
その後、使用メモリが77MBに達すると落ちることが判明し、大半のメモリはキーに設定したSVG画像が消費していました。この状態で何度も高速でキーボードを開いたり閉じたりしているとメモリの解放が間に合わないか何かで77MBに達してしまう瞬間ができてしまい、突然アプリが落ちるという不具合でした。
SVG画像はUI改善の過程で設定したものだったのですが、SVG画像がそんなにメモリを消費するとは思っていなかったので、いつのまにか使用メモリが膨大していたことに気付いていませんでした。
SVG画像もTrueTypeフォントもデータ形式がよく似ているので、描画コストは大差ないように思っていたのですが、実験してみると、同じ形状の字であってもフォント描画の方がはるかに低コストで済むことが分かりました。
そこで、キーの文字はすべてフォントで表現することにしました。
10年以上前(平成23年)にTTEditというWindows向けフォント作成ソフトを購入していたことを思い出し、過去の購入メールからライセンスキーを探し出し、そのライセンスキーでも動作する古いバージョンをダウンロードし、SVG画像の代わりとなる自作フォント(キー専用フォント)を作りました。
自作フォントを作るにあたっては、「あ」のキーには「あ」という字を描き、「か」のキーには「か」という字を描くわけですが、1つのキーに複数の文字を詰め込みたい場合には、1文字分の領域に対して複数の文字をまとめて描くというような工夫をしました。
たとえば以下のキーは、「小」「ゐ」「ゑ」など何文字も組み合わせて表現しているように見えますが、実際には「小」という文字を自作フォントで表示しているだけです。「小」という字のデザインの中に「ゐ」や「ゑ」を含めてしまっているので、「小」という字を表示するだけで以下のようなキーデザインが低コストで描画されるという仕組みです。
確定キーの「確定」という表記も2文字に見えますが、実際には「確」の字に「確定」の2文字を納め、「確」の字だけを表示しています。「空白」も「次候補」も「あいう」もすべて同じ仕組みです。
このほか、全面的なリファクタリングを兼ねてソースコードのメモリ効率を改善し、起動するだけで50MBを超えていた使用メモリを16MBまで削減しました。
以上により、アプリが突然落ちる不具合は起こらなくなったのですが、このメモリ効率化作業だけで10月の工数を使い切ってしまいました。
令和5年11月3日~5日(締切を延ばす)
本来ならば、この連休最終日に審査に申請完了するつもりだったのですが、10月の積み残し機能が消化しきれておらず、開発期限を1週間先に再設定しました。
令和5年11月12日(機能テスト)
積み残し機能はこの日までにすべて完成しました。ただ、この時点でリリース予定日まで4日しかなく、変換精度の調整をする時間がありませんでした。
しかし、精度は悪くても正常に動くことは動くので、ここで開発を切り上げることとし、さまざまな機種のエミュレータで動作確認を実施したり、審査用のメタデータ(PR画像など)の作成をしたりしました。
令和5年11月13日(ファイル消失事故)
早朝7:50、以前登録して期限切れになっていたApple Developer Programのメンバーシップを有効化し、アップロード作業を開始しました。
アプリのバイナリファイルをApp Store Connectにアップロードしようとしたところ、以下のようなエラーが発生しました。
Asset validation failed Invalid Bundle.
The bundle at 'ClassicalJapaneseKeyboard.app/PlugIns/keyboard.appex' contains disallowed nested bundles.
Asset validation failed Invalid Bundle.
The bundle at 'ClassicalJapaneseKeyboard.app/PlugIns/keyboard.appex' contains disallowed file 'Frameworks'.
Asset validation failed Invalid Bundle.
The bundle at 'ClassicalJapaneseKeyboard.app/PlugIns/keyboard.appex/Frameworks/mecab.framework' contains disallowed file 'Frameworks'.
最初は設定が悪いのかと思い、同梱に関する設定を色々変えてみたのですが、解決しませんでした。
ネット上の記事などを読んで調査した結果、キーボード拡張で別のプロジェクト(MeCab)を参照していること自体が原因である可能性が高いと判断し、別の方法で同梱することにしました。
といっても深く考えている時間はないので、MeCabのフォルダをキーボード拡張フォルダに移し替え、C言語とSwiftをブリッジするという安直な方法をとることにし、MeCabフォルダをコピペで移し替えようとしました。
ここで、事故が発生しました。
コピペで移し替えただけのつもりだったのですが、何か変な操作をしてしまい、MeCabのファイル一式をプロジェクトから消してしまったことに気付きます。Xcodeのファイルリストで見えているファイルと実際に存在するファイルはつながりが見えにくく、意図せず参照が切れたり二重に登録されたりすることが今までにもよくあったのですが、今回は少し事情が違いました。
ゴミ箱から対象のファイルをすべて復元しようとしたのですが、なぜかフォルダしか復元できないのです。フォルダの中身を見てみると、あんなにたくさんあったファイルがどこにも見当たらず、空のフォルダをゴミ箱に捨てたり元に戻したりする操作しかできなくなっていました。
MeCabのプロジェクトはGitにコミットしていなかったので、自家改造版MeCabが世界から完全に失われてしまったことにここで気付きます。
平日の朝だったので、ここで作業を中断して仕事に行きました。消えてしまったものは仕方ないので、この時点では、リリースは延期するつもりでいました。
帰宅後、どこかにファイルが残っていないか再びゴミ箱を探していたところ、「Mecab copy」というフォルダを発見します。これは、Mecabフォルダ移し替えのときに誤ってフォルダを二重に登録してしまい、すぐに消したものです。
試しに中身を見てみると、なんとすべてのファイルが残存していました。
すぐにバックアップを取り、再びキーボード拡張フォルダに移し入れます。
リリースは延期するつもりでしたが、間に合う可能性が出てきました。
ところが、MeCab(C言語)とキーボード機能(Swift)のブリッジを作成して連携すると、MeCab側にエラーが大量発生してしまいました。
これには何時間も格闘しましたが、結局この日のうちには解決できず、次の日に回すことになりました。
令和5年11月14日(審査申請)
どうしてもエラーが消えません。
リリース予定日まであと2日しかなく、審査に一発合格すると仮定しても、この日に提出まで済ませておかなければ間に合わない可能性があります。それに、アップロード時のエラーが本当にMeCabフレームワークの同梱にあるのかどうかすら未検証の状態です。それをクリアしても、また別の問題が出現する可能性もあります。
よく観察してみると、エラーが出ている部分の大半は、本アプリの動作には直接関係がなさそうな部分がほとんどでした。そこで、関係がなさそうな部分については根本解決をあきらめ、モグラ叩き式に表面的な修正を加えていったところ、ついにエラーは出なくなりました。
動作確認してみたところ、すべて正常に動きました。メモリの挙動も正常で、プロジェクト統合前の状態と見分けがつきません。どうやら統合に成功したようです。
これをコンパイルしてApp Store Connectにアップロードしたところ、今回は何のエラーも起こることなく、すべての処理が成功しました。
早速、リリース日時を「R5/11/16 1:00JST以降」と設定し、審査に提出しました。
ところが提出後、アプリを実機で触っていたところ、アプリ内に公式サイトへのリンクを貼っていたことに気付きます。以前、別のiPhoneアプリを制作したときに「公式サイトへのリンクを貼っている場合にはトラッキングの許可をユーザに求める必要がある」ということで不備を指摘され、審査で却下されたことがあります。
今回もアプリ内にリンクを貼っているにもかかわらず、「トラッキングの許可」を求めるポップアップ機能を付けるのを忘れていました。これは却下される可能性が高いです。
ここで自分で申請を一時取り下げたのですが、ポップアップ機能を付けると不具合が紛れ込んだり、許可を求める文言が悪いなどの理由で却下されたりするおそれがあったので、アプリ内のリンクをすべて削除する方針を取りました。変に機能を追加すると指摘ポイントが増えてしまうので、仕方ありません。
修正版をアップロードし、審査に提出しました。
令和5年11月15日(アプリが却下される)
提出も済んだので、久しぶりに旧仮名キーボード開発記を更新しようと思い、noteに原稿を書き始めました。以下の記事を書いていたのがこのときです。
記事執筆中の2:07に、審査ステータスが「審査待ち」から「審査中」に切り替わりました。その後、ずっと起きて審査結果を待っていたのですが、5:00になってようやく審査結果が出ました。
結果は「却下」でした。
却下理由を読んでみると、アプリ名のサブタイトルに不適切な文言が含まれるという内容でした。「旧仮名使いで入力変換できる無料キーボード」というサブタイトルのどこが不適切なのだろうかと思ってよく読むと、「無料」という語が含まれるのは規約に反するとのことでした。
すぐに修正し、5:11に再提出を済ませました。提出後、しばらく審査状況を見ながら待っていたのですが、一向に再審査は始まりません。また翌日の深夜2時まで待たなければならないのかもしれないと思い、寝ることにしました。
この日も平日で仕事だったのですが、審査は15:09から始まり、15:44に完了していました。
結果は「合格」でした。
リリース予定日の前日夕方になり、ようやくリリース可能な状態まで漕ぎつけたことになります。ステータスが「審査中」から「リリース待ち」に変わり、16日1:00の自動リリースを待つのみとなりました。
令和5年11月16日(公開日)
深夜1:00、自動でリリースが完了しました。App Storeを見てみると、ページがきちんと存在し、ダウンロードできる状態になっていました。
まだ検索には引っ掛からないようでしたが、とりあえず公開に成功したので安心しました。
この日はリリースに寄せてnoteを公開した後、疲れて寝ました。
その日の夜23:00頃、夕食を食べながら、数年前に開発物を発信するために作ったTwitterアカウントがあったことを思い出し、旧仮名キーボード公開時のnoteへのリンクを一応ツイートしました。
さて、このタイミングになって、個人アカウントよりも公式Twitterアカウントを作成したほうがいいと思いつきました。また、どうせなら公開日当日にツイートしたいと思い、大急ぎでアカウントを作成し、23:59に滑り込みで最初のツイートを公開するに至ります。
令和5年11月17日(追加修正)
リリース後、なぜかアプリダウンロード画面での対応言語が「英語」になっていることに気付き、アップデートを掛けました。また、異体字セレクタの初期設定をONと定義したのは失敗だったかもしれないと思い、まだ利用者はいないようだったので、OFFが初期値となるようにサイレント仕様変更を行いました。
令和5年11月18日(初のダウンロード)
初めて一般ダウンロードがあったのは、おそらく公開2日後の11月18日です。公式Twitterアカウントに通知が来ていることに気付き、確認してみると、すでに利用者が何人も現れているようでした。
特に影響が大きかったと考えられるのは國語問題協議會(@kokumonkyo)様のリツイートで、この日のうちにダウンロードしていただいた48人(延べ)の方々の9割以上は、そのリツイート経由で旧仮名キーボードを知ったのではないかと思います。
令和5年12月4日
以上の変遷をたどり、今に至ります。
現在データが出ている範囲(12/2まで)で集計すると、111人の方々が旧仮名キーボードをダウンロードしてくださっています。
新規利用者数は11月18日以降、ほぼ毎日増え続けています(11月30日だけはダウンロード数0でしたが、それ以外の日については常に新規ダウンロードがある状況です)。
すでにApp Storeで評価を付けてくださっている方々もいます。
また、note経由でサポートもいただきました。ありがとうございます。
問い合わせ窓口へも数件フィードバックが寄せられており、メールアドレスを入れてくださっている方々に対しては返信を差し上げています(※もし届いていないようでしたら迷惑メールボックスに振り分けられている可能性がありますので、ご確認ください)。
Twitter上でのコメントや要望も、返信は差し上げていませんが、見かけた範囲についてはメモしています。
ニッチなアプリですが、応援していただいている方々は確実にいるので、今後も積極的に品質向上に取り組んでいきたいと思います。
開発史まとめ
長文になりましたが、今日までの開発の変遷については以上です。
これまで述べた内容の簡潔版を、以下ページにまとめました。
今後も何か変化があればここに追記していきます。
次回予告
問合せ窓口に機能要望がいくつか届いているので、次回はそれについて検討します。