子どもがいまだに飛行機好きなので、レーダーをアップグレードした
(jacobbartlett.substack.com)- 個人向けiOSレーダーアプリ Aviator 2.0 は、12月初めから続いていた OpenSky Network の障害後に再び動作するようになり、実際の使用で明らかになった不便をまとめて改善したアップデート
- 新しいコントロールメニューは 段階的開示 の構造で、主要な操作と高度なツールを分け、SwiftUI の modal detent と背景インタラクションによってレーダー画面を隠しにくい構成になっている
- 遠すぎる航空機まで拾ってしまう問題は 二段階ズームトグル で軽減し、MapKit の camera distance を 70km または 100km に切り替える方式で実装
- OpenSky Network API の
origin_country、高度、categoryデータを活用して、国旗表示、曇天時の低高度フィルター、ヘリコプター・衛星・機体サイズ別のアイコン分類を追加 - ユーザーは OpenSky Network のログイン情報 で HTTP Basic 認証を利用できるが、2.0 ではパスワードが User Defaults に保存されるため、機密性の高いパスワードの使い回しは避けるべき
Aviator 2.0 アップデートの背景
- Aviator — Radar on your Phone は、子どもと一緒に飛行機を探すために作った iOS レーダーアプリ
- 前回の記事のあと、新しいリリースや収益化の機会を考えることもできたが、アプリは12月初めから OpenSky Network の障害によりユーザーにエラーを返していた
- アプリを再び開いたとき、ずっと表示されていた 502 エラーの代わりに飛行機検知の通知音が鳴り、正常動作を確認した
- その後、2回の夜の作業で既存のアイデアを反映した Aviator 2.0 の作業を進めた
レーダーをあまり隠さない新しいコントロールUI
- 2.0 ではコントロールを別メニューへ移し、重要な操作を上部に、使用頻度の低い高度なツールを下部に配置した
- この構造では 段階的開示(progressive disclosure) を採用している
- メニューは SwiftUI の modal で実装され、2つの
presentationDetentsを持つprimary: 画面高さの0.15extended: 画面高さの0.4
- ドラッグインジケーターでメニューを拡張できることを示し、
presentationBackgroundInteraction(.enabled)によりメインのレーダーUIが影に覆われないようにしている presentationBackgroundには Paul Hudson の emboss effect を適用し、実際のレーダー制御盤のような金属質感を加えた- 2.1 では TipKit を活用し、若い Apple ユーザーでも段階的開示の構造に気づけるようにする予定
ズームレベルとレーダー範囲の調整
- 1.0 ではレーダーがうまく動きすぎて、地平線の向こうや地形の裏側にいて見えない航空機まで拾ってしまう問題があった
- ロンドン郊外のように段状の地形と島状に連なる環境では、これが実用上の不便になっていた
- 開けた場所では遠くの飛行機も見えたため、単なる感度の問題とだけは言えなかった
- 解決策は ズーム機能 を入れることだった
- MapKit SDK の
cameraにdistanceをメートル単位で渡し、地表の拡大・縮小を実装したzoomedが true なら70 * 1_000- false なら
100 * 1_000
- 週末リリースに合わせて素早く実装する中で、拡大UIを強調するためにレーダー円を1つ削除した
- 当初は
Sliderでズームレベルを扱おうとしたが、A17 チップでも十分なフレームレートが出なかったため、現在は 二段階ズームトグル を使っている
OpenSky Network データで追加された機能
-
国旗表示
- OpenSky Network API は航空機トランスポンダーからさまざまな情報を収集するが、1.0 ではこのデータを十分に活用していなかった
- 2.0 では各飛行機アイコンの下に出発国を 絵文字の国旗 で表示するトグルが追加された
- 実装は
origin_countryの値に基づく - API が提供する出発国の文字列を受け取る
- オンラインで見つけた国名リストで2文字の国コードに変換する
- 国コードを Unicode スカラーに変換して国旗絵文字を構成する
- ユーザーが機能を有効にすると、MapKit annotation のテキストとして
flight.flagを表示する
-
曇天モード
- イギリスの曇りの日には、アプリに表示される飛行機のかなりの数が雲に隠れて実際には見えなかった
- 高高度の航空機を隠すボタンを追加し、晴天モードと雨天モードを切り替えられるようにした
- OpenSky Network から受け取った高度データを使い、低い雲の基準となる底高度として 2.5km を使用する
geo_altitude < 2500.0ならisLowAltitudeが true になるcloudy設定が有効なら、低高度の航空機だけを MapKit annotation に表示する
航空機アイコンの改善
- 公園でテストしているとき、頭上をヘリコプターが通過したが、Aviator はそれを通常の飛行機アイコンで表示していた
- OpenSky Network API はクエリパラメータを追加すると、トランスポンダーが属する航空機の種類を示す
category属性を提供する - このカテゴリーには次のような項目が含まれることがある
- 15,500ポンド未満の軽量航空機
- 300,000ポンド超の重量航空機
- ヘリコプターのような回転翼機
- 宇宙・大気圏通過ビークル
- パラシュートまたはスカイダイバー
- 最新アップデートでは 航空機サイズの等級 を区別し、衛星とヘリコプターを別アイコンで表示する
AircraftCategoryenum で画像、絵文字、スケール値を分離したrotorcraftはxmark.circle.fillSFSymbol を使用spaceTransatmosphericは 🛰️ 絵文字を使用small,large,heavyにはそれぞれ0.6,1,1.5のスケールを適用
- ヘリコプターの絵文字は単色の平面に変換すると丸みが強すぎて見えたため、より抽象的な円の中の十字 SFSymbol を選んだ
- 絵文字を画像のように扱うために
Textをスケーリングした後Rectangleのマスクとして使い、色と CRT 画面効果を適用した
ユーザーの OpenSky Network ログイン
- ユーザーが自分で OpenSky Network の認証情報 を入力する機能が追加された
- この機能は Android 版に続いて要望の多かった機能の1つで、未認証 API 利用時の rate limiting を避ける目的がある
- 全体のコントロールメニューからアカウントを入力でき、登録ページへのリンクも提供している
- SwiftUI の
TextFieldとSecureFieldで実装されている@AppStorage("username")@AppStorage("password")
- 2.0 では素早く本番投入する過程で、パスワードを User Defaults に保存している
- 次のリリースでは Keychain に保存する予定で、現時点では機密性の高いパスワードを再利用しないほうがよい
- 入力されたユーザー名とパスワードは Base64 でエンコードされ、API リクエストの
AuthorizationヘッダーにBasic認証として付与される
まとめ
- Aviator 2.0 は、子どもと一緒に遊べるアプリを継続的に改善するためのアップデート
- 機能アイデアや ASO のヒントをコメントで募集し、Aviator — Radar on your Phone 2.0 のダウンロードとレビューを呼びかけている
1件のコメント
Hacker News のコメント
2か月前にかなり人気だった記事の続編。
0: https://news.ycombinator.com/item?id=38435908 My toddler loves planes, so I built her a radar (1304 points, 56 days ago)
アプリを見て、DVD のプログラミングをしていた頃に経験した問題を思い出した。トグルボタンで、現在どのモードが有効なのかが明確ではない。
旗や雲のアイコンが現在のモードを示しているのか、そのモードに切り替えるために押すものなのか迷う。天気のトグルも、雲を押して曇りモードを見たいということなのか、晴れた画面に切り替えるということなのか、逆に感じられる。
今やっているプロジェクトでも、+/- ボタンが時間範囲ウィンドウのサイズを調整するのだが、開始時刻では + が秒の値を減らし、- が増やす。終了時刻ではその逆。ウィンドウサイズの観点ではどちらも予想どおりなので、結局はユーザーの視点を明確にする必要がある。
YouTube の字幕トグルも、黒地に白文字と白地に黒文字の間を行き来するので、とりあえず押してみて、口は動いているのに字幕が見えなければ別のアイコンモードを試す必要がある。
タッチスクリーンに移行したことで、状態を持つ位置入力フィードバックに関する常識が失われたように感じる。
しかも、混乱するのはその通り。最後のバグ修正で、雲のアイコンだけ他のものと逆にしてリリースしてしまった。
レーダースキャンが飛行機を通過するときに点滅表示され、位置は固定されたまま次のスイープまで徐々に消えていくと、本当に格好よさそう。
さらに、デバイスの現在の GPS 高度と位置を見て、OpenStreetMap の周辺の建物、丘、標高を使い、方位角ごとに見えるスカイラインを計算できるとよさそう。そうすれば地図上にレーダー遮蔽のように表示できる。丸太を通過する魚群探知機や、他の船に遮られる船舶レーダーのような感じ。
そう作ったら、業界の人たちはスマートフォンがどうやって放射状スキャンをしているのかと首をかしげそう。
[1] https://www.researchgate.net/figure/Occlusion-percentage-for...
ブログに残した考えだが、幼児の親として、色選びがいちばん重要だという話には同意する。
楽しいサイドプロジェクトなので、まだ実装していないかもしれない機能アイデアがいくつかある。1つ目は、スマートフォンのカメラと iPhone の AR 機能を使って、航空機がいるおおよその位置に点を表示するライブビュー。ユーザー位置と ADS-B 情報から計算するコードを少し書いたことがある。
2つ目は、航空機を「見た」または「見逃した」としてマークし、そのフィードバックを表示内容の調整に活用することもできる。
3つ目は、バッジと統計。娘さんがうちの子と似ているなら、アプリでバッジをもらうのを喜ぶはず。過去の観測記録をローカル DB に保存して、「見た航空会社数」「見た航空機の機種数」「最長飛行時間」「最短飛行時間」のようなものを追跡できる。ただし、子ども向けアプリをゲーミフィケーションすることに伴う問題は十分理解している。
Robux のようなデジタル通貨に 30 ドルを使うべきではない理由をよく話している。テニスラケットや靴のように実際の価値がある物とは違うと説明している。
だからゲーミフィケーションには抵抗していて、バッジや価値のないデジタルな記念品を得るために何時間も反復作業に吸い込まれないような道具を与えたいと思っている。
子ども向けのアプリなら、こうした機能は入れないほうがよいと思う。広告もなく、ゲーミフィケーションもされていないが、生活に実際の価値を加えてくれるアプリが存在することを示せる。
HN の人たちの中で、これを Android に移植するオープンソースのクラウドソースプロジェクトをやってみたい人はいるだろうか?
ライセンスは推測だが、最初の GitHub リポジトリを作る人が、作者の「意欲的な Android エンジニアが自分で移植してくれるのを待っている。記事には十分な詳細を書いておいた。全員に無料で提供するだけならやってよい」という文言を使えばよさそう。
このレーダーアプリに高品質な Android アプリとして貢献できなかったとしても、“An app can be a home-cooked meal”[0] のパラダイムに合う何かを移植してみることに時間を使うのはよさそう。単一のビジョンとパラダイムで作られていて、肥大化、広告、追跡などがないため、コードを理解しやすい可能性が高い。
この提案が、プログラミングの楽しさを取り戻す道につながるかもしれない。
0: https://news.ycombinator.com/item?id=38877423
少し別の話ですが、方向音痴の人間として、スマホで最も重要な機能は、地図上の小さな矢印が自分がどちらを向いているかをどれだけ正確に示してくれるかです
Androidを使っていますが、確信が持てないときは青い不確実性の円錐を表示し、たまに8の字にスマホを動かしたり、周囲の建物に向けたりして補正するよう求めてきます
技術的にここでの限界は何なのでしょうか? iPhoneはAndroidより優れているのでしょうか? ハードウェア、加速度計、コンパス、GPS信号、ソフトウェアのうち何が問題なのでしょう? いまだにかなり頻繁に混乱して、円錐を見当違いの方向に表示します。iPhoneのほうが明らかにうまく動くなら、乗り換えをほぼ考えるほど重要です
GPS側の限界があるのだろうと思っていましたが、CoreLocationの方位デリゲートは、少なくとも私の端末の120Hzフレームレートでは方位を完璧に返します
Google Mapsが単にあまり良くないだけかもしれません
どちらも方位値が間違う頻度は同じくらいです。ただし、使用体験に基づく推測であって、確定的な事実ではありません
以前のiOSでは遅い矢印がかなり気になりましたが、今はハードウェアが速くなったことで、他のプラットフォームの跳ねる矢印のほうが目立ちます
要するに、最新ハードウェアの大半は、空間と時間における自己位置をかなり正確に把握する能力は同程度です。ただし、現在のデータで推測航法と姿勢推定をどれだけうまく行い、手に持った状態でユーザーが期待するノイズフィルタリングをどう扱うかは、ナビゲーションソフトウェアによって異なります
Tony Hawkのゲームのおかげでヘビーメタルにはまりました。THPS3のMotörhead「Ace of Spades」、THPS4のIron Maiden「Number of the Beast」がきっかけだったので、プラットフォーマーゲームからヘビーメタルへ続くパンくずの道はあり得ます
最も重要なユーザーを確実に幸せにしたという点で、よくやりました
素敵です。ついでに18年後に娘さんが航空管制試験に合格したか確認するために、
!remindmeを設定したくなります9/11後の世界でも、子どもたちはコックピットに招待してもらえるのか気になります
ボタンを押して、父が動いている計器を指さしてくれたことをぼんやり覚えています。席に戻るとき、自分が世界でいちばん大きな子どもになったように感じたことは鮮明に覚えています
9/11後には、そういうことは確かに起こりにくいでしょう
逆に着陸後に子どもがコックピットを見られるか尋ねると、成功する可能性がずっと高いです
飛行中は乗務員もほとんど入れず、たまにチーフパーサーだけが入れることがあります。子どもたちは搭乗時にコックピットのドアがまだ開いていれば尋ねます
JetBlueの米国内線でした
子どもの頃、旅行中に航路上でコックピットを見せてもらい、Deltaのウィングピンをもらったものが、今でもどこかにあります。今でも覚えている素晴らしい体験で、他の子どもたちもその一部だけでも体験できるといいなと思います