1 ポイント 投稿者 GN⁺ 2025-05-24 | 1件のコメント | WhatsAppで共有
  • 2025年になっても、iPhoneでMP3音楽を自由に再生することには制約が多い
  • Appleおよびサードパーティアプリの多くは有料サービスであるか、ユーザーの使い勝手が不十分
  • 自作アプリは全文検索iCloud対応ローカル優先環境などを提供
  • React Nativeなどのクロスプラットフォームアプローチには、ファイルシステムの制約と安定性の問題から限界があった
  • SwiftUIとSQLiteベースの設計により、独立性が高く拡張しやすい音楽管理体験を実現した

概要

2025年になっても、ユーザーが自分で所有するMP3ファイルをiPhoneで自由に再生するのは難しいという現実に対する不便さを、自ら解決しようとして、開発者が自分自身で音楽プレーヤーアプリを作るに至った経緯と結果を紹介する。Appleの音楽サービスや外部アプリにはさまざまな制限や課金モデルがある一方で、自作したアプリはユーザーの音楽ファイル管理と再生に最適化された体験を提供する。

音楽プレーヤーを自作した理由

  • Apple MusicやiCloud Music Libraryなどのクラウド同期機能は、有料サービスを契約しなければ使えない
  • サブスクリプションをやめると、自動同期や音楽フォルダへのアクセスがすべて遮断される
  • 既存の音楽ライブラリ統合や汎用デバイス活用において、所有者としての権限が欠けていると実感した
  • 「購入したスマートフォンを使って、本当に必要な機能は自分で作ることもできる」という自己決定性を実現したかった

Appleとサードパーティの音楽再生ソリューション分析

Apple標準アプリ

  • Filesアプリを使ってiCloudフォルダ内の音楽ファイルを再生することはできるが、プレイリスト管理、メタデータ並べ替え、キュー操作などの基本機能が弱い
  • 音楽鑑賞に最適化されていないユーザー体験になっている

サードパーティアプリ

  • App Storeにはさまざまな外部アプリがあるが、サブスクリプション型の課金モデルが多く、アプリごとに機能水準もばらつきがある
  • Dopplerのような一部の有料(買い切り)アプリもあるが、大規模なiCloudフォルダに対する検索・インポート体験はスムーズではなかった

「ビルダーモード」へ進んだ技術的な道のり

  • 自分で音楽プレーヤーアプリを作ると決意した
  • 必要な機能: iCloudフォルダ全体に対する高速な全文検索、公式音楽アプリ水準の音楽管理機能(キュー、プレイリスト、並べ替えなど)、そして直感的なインターフェース

React Nativeでの最初の試み

  • Swiftでの過去の不便さ(以前はasync/await未対応など)から、React Native/Expoを好んでいた
  • オープンソースのテンプレート活用などでUI実装は比較的順調だったが、ファイルシステム(iCloudフォルダ)へのアクセスと同期の処理で、アプリクラッシュや機能上の限界を感じた
  • iOSのサンドボックス方針では、明示的な権限なしに外部フォルダへアクセスできないと気づき、Swiftへ移行した

SwiftUIを選んだ理由

  • SwiftUIの宣言的UIパラダイムモダンなasync/awaitとSwift Actor対応を活用
  • UIとデータロジックを徹底的に分離し、クリーンなデータフローとドメイン並行処理を実装
  • LLM(OpenAI o1、DeepSeekなど)の活用を最適化し、生成されるUIコードの依存性最小化にも役立った

アプリのアーキテクチャとデータモデル

  • SQLiteをデータストアとして採用し、**全文検索(FTS5)**をそのまま使えるためCoreDataではなくこちらを選択した

  • アプリの3つの主要画面/モード:

    1. ライブラリインポート: iCloudフォルダごとにオーディオファイルのパスをDBへ一括保存し、柔軟な検索・管理を支援
    2. ライブラリ管理: プレイリスト、曲の分類、編集など
    3. 音楽再生: キュー管理(リピート、シャッフルなど)と基本的な曲コントロール
  • ライブラリインポート時のユーザーフロー:

    • 初期の空状態から「Add iCloud Source」でフォルダを選び、ツリーをスキャン
    • インデックス作成が完了するとライブラリタブへ移動し、キーワード別のリストとミニプレーヤーを表示
    • 新しい曲を追加するとバックグラウンドで自動マージされる

バックエンド風のロジックレイヤー

  • Web/クラウド系スタートアップでの開発経験をもとに、ロジック層とUI/ViewModelを徹底的に分離
  • **ドメインレイヤー(Swift actors)**が主要なビジネスロジック(インポート、検索、キューなど)を持ち、スレッドセーフ性を確保
  • UI更新はViewModel経由できれいに分割し、ファイル同期・再生・UI間の依存を最小化して保守性を高めた

SQLiteで全文検索を実装

  • iOS 11以降では追加設定なしにFTS5対応SQLiteを利用できる
  • 外部検索インデックスやサーバーなしで高速検索を実現
  • SQLite.swiftライブラリで通常クエリを処理し、FTSクエリでは直接SQL文を使用

FTSテーブル構造

  • songs_fts: 曲のartist、title、album、albumArtistなどをインデックス
  • source_paths_fts: ファイルパス、ファイル名をインデックス
  • メインテーブルと並んで存在し、UIでは検索(READ)専用に使用
  • インデックス更新はDBトランザクションで処理し、データ整合性を維持

あいまい検索とランキング

  • 入力値の末尾にワイルドカードを自動追加し、BM25ベースで関連度順にソート
  • 全体として、ネットワーク依存のない予測可能なデータ構造と強力なローカル検索環境を実現した

iOSファイルシステムとブックマークの活用

  • iOSはmacOSと異なり、security-scoped bookmarksをサポートしておらず、外部ファイル拡張アクセスの永続性が不足している
  • パス情報しか保存されないため、再アクセス時にはユーザーが再度権限を承認する必要がある
  • 解決策として、アクセスを許可した時点でファイル自体をアプリのサンドボックスへコピー保存する
  • バックグラウンドで自動コピーし、ファイルインデックス作成速度も改善
  • 端末再起動後は外部ファイルの直接再生が依然として難しく、iOSのファイルアクセス制約の厳しさを示している

AVFoundationベースの再生とインターフェース設計

  • AVFoundationフレームワークAVURLAssetを使ってオーディオファイルのメタデータを解析
  • track numberなど一部の項目は手動で解析(ID3タグを活用)
  • オーディオ再生にはAVAudioPlayerを使用し、コントロールセンター連携のためMPRemoteCommandCenterとDelegateプロトコルを実装

開発後に感じたこととAppleの方針への考察

不便だった点

  • Xcodeの制約的な環境: SwiftUIのライブプレビューは進化しているが、VSCodeやFlutterの使い勝手には及ばない
  • エディタの柔軟性不足: NeovimやVSCodeでSwift LSPを活用するには追加設定が必要で、完成度も低い
  • 一部SDKの奥まった部分はObjective-C寄り: メタデータ検索などでモダンなSwiftに親和的なAPIが不足
  • iCloud連携のデバッグが面倒: SwiftUIプレビューではクラウド機能を完全に実装できず、直接モックを構築する必要がある

良かった点

  • Async/awaitにより、I/Oバウンドな並行処理コードが大幅に書きやすくなった
  • 豊富なネイティブライブラリ: オープンソースバインディングの限界を離れ、より多様な機能を開発可能
  • SwiftUIの宣言的UI設計: React的な強みと高い生産性を実感

結論: 開発はもっと簡単になるべきではないか

  • 1.5週間の開発でローカル/オフライン音楽プレーヤーという目的を達成
  • 実際にはアプリ自体の配布にも制限がある: 開発者証明書がなければ7日後に使用不可となり、年間99ドルの開発者登録が必要
  • EU DMA Act後もサイドローディングは完全には開放されておらず、個人・趣味開発者には依然として制約が続く
  • PWAもiOSでは主要API未対応などの制限がある(Web Bluetooth/USB/NFC、Background Syncなど)
  • AIによって開発の障壁は下がったが、iOSだけは人為的な規制で参入障壁が高い
  • 独立開発者とユーザーの権限制限は依然として続いており、iOSの閉鎖性は今なおイノベーションの障害要因となっている

1件のコメント

 
GN⁺ 2025-05-24
Hacker Newsのコメント
  • 25年間にわたってFLAC形式で音楽コレクションを築いてきた者として、昨年Androidスマホと1TBのMicroSDカードを買い、全ての音楽をポケットに入れて持ち歩けるようになったことに大きな満足感があるとのこと。音楽を“借りる”のではなく、自分で管理したい人や、業界が押し出す曲をストリーミングで聴いたり広告を我慢したりしたくない人は、自分だけではないはずだと感じるという話。こうして自分でアプリを開発する事例を見るのは素晴らしいという感想
    • 技術的には数年前から十分追いついており、ただ自分があまり向いていないフォーマットにこだわっているだけではないかという意見。適切な再エンコードを使えば、音質差を感じられないほど透明な音質のまま、はるかに小さい容量に全曲を収められるとのこと。バックアップ用としてデスクトップにFLACファイルを置いておく方法を推奨
    • 本当にコレクションをしっかり築いている人だという称賛。自分の音楽コレクションではFLAC/APE/ALAC/WavePackのようなロスレス形式が約25%を占め、容量は3TBを超えているという。そのため移動中の音楽再生に苦労しており、どの曲をモバイル機器に移すか事前に選ぶのが難しい状況だと共有
    • Androidでアルバムカバーやタイトル情報が正しく反映されなかったり、ランダムに変わったりする問題をずっと経験している。Androidのバグのように見えるが、解決した人がいるか知りたいという話
    • 自分もFLACだけで個人コレクションを集めているが、まだ25年にはならない。すでに1TBを超えており、NavidromeサーバーとSymfoniumクライアントを使っていてとても満足しているとのこと。最近は2TBのmicroSDカードも出始めているので、価格がもっと下がれば購入するつもりだという
  • 昔のwinamp時代から音楽を聴いていて、今でもストリーミング時代にローカル音楽ライブラリをフォルダ単位で整理して使っている。自分も他のコメント投稿者たちのように、オフラインで音楽を楽しむためのオールドスクールな音楽プレーヤーを趣味で自作したとのこと。1ページのhtml/jsアプリで、フルキーボード操作とシンプルなキュー(再生リスト)機能がある。https://nobsutils.com/mp を見てほしいとのおすすめ
    • 自分も27年前からwinampのUIは本当に優れていたと思っている。フォルダごとのファイル集約、全体シャッフル再生、特定ディレクトリだけを再生するシンプルさが最大の強みだと強調
    • 自作アプリが本当によく動くというフィードバック
    • 自分にとってはfoobar2000が最高の音楽プレーヤーだった。今はCogアプリで代用している
  • 自分でWebアプリを開発し、アルバム全体を聴きながら、端末を切り替えても中断した位置から再開できる機能を実装したとのこと。アルバムを最初から最後まで通して聴くのに、YouTube Musicのようなサービスは再生位置をきちんと記憶できなかったり、端末切り替えが不便だったりしたという。自作のWebアプリではURLを貼り付けるだけでyt-dlpを使ってサーバーにダウンロードされ、そこからストリーミングできる。再生位置を常に記憶するので、車で聴いていた位置をそのまま職場のノートPCで続きから再生できるという。NTS Radioなど他ソースのミックス追加もうまく機能している
    • YouTube Musicでキュー保存や端末間のシームレスな切り替えができない点に共感する。開発者が作ったそのWebアプリを一度使ってみたいという反応
  • この記事では物理デバイスだけでなく、それを管理・再生するソフトウェアについても扱ってほしかったという意見。数年前、10歳の息子にmp3プレーヤーを買ってあげようとしたが、適切な製品がほとんどなくて衝撃を受けたという。AppleがiPodを終了させたことで市場に大きな空白ができたのに、まだ誰もきちんと埋められていない状況だとのこと。iPod shuffle(USBスティック型)は自分が使った中で最高のmp3プレーヤーで、小さく、差し込み式で、バッテリーも長持ちし、非常に満足していたという。画面なしでシャッフル専用というコンセプトもむしろ利点だったが、こうしたシンプルな機器は今のハードウェア市場では再現されていない。ソフトウェアやDRMの問題だと受け止める人もいるが、音楽再生だけをしてくれる安価で携帯性の高い機器があればいいのにと思うという話
    • 大きな変化の主因はiPodの消滅ではなく、Spotifyとスマートフォンの普及だと思うという意見。この2つが市場の大半を占め、他の選択肢をすべて押しのけたという見方
    • Fiioがこのカテゴリの商品をいくつも出しているという情報共有。例1 例2
    • ハードウェアやソフトウェアの問題ではなく、需要の問題だと思うという意見。中国メーカーがMini iPhone 16やMini S24のように、スマートフォン機能を備えつつ音楽再生もできる小型端末を$50〜$100で販売しているため、多くの親はmp3プレーヤーよりもそうした機器を子どもに買い与える可能性が高いという。14歳になるまで携帯電話を持たせない親はそれほど多くなく、それに合わせて市場需要が形成されていると指摘
    • Sonyはいまでも"walkman"ブランドで良いプレーヤーを出し続けている。公式リンク 10歳の子どもにはやや高いかもしれないので、中古をeBayで買うのを勧めるとのこと
    • SanDisk Clipのようなmp3プレーヤーが家のどこかにある気がする、という話から呼び起こされた思い出
  • この記事を楽しく読んでおり、まだ読み終えてはいないが、開発者が小さく細かな決断をどう下し、その背景に何があるのかを読むのが良かったという感想。ほとんど全ての音楽アプリでUXやレイアウトが似通って見えるので、いつもそれら全ての音楽アプリと“ボクシング”しているような気分になるという。新しい試みに挑戦する人たちを応援したいとのこと
  • 自分はいまでもApple Musicアプリでローカルファイルだけを使っている。Apple Musicのストリーミングサービスはオフにし、macOSのApple Musicアプリに全音源を読み込んだうえで、スマホをノートPCにつないで2007年のように同期して使っているという。自分の音楽は頻繁に変わらないのでこの方法で問題なく、有線同期から感じるノスタルジーもあるとのこと
    • iTunesによる自動Wi‑Fi同期も今なお問題なく動作するとの補足
  • 「革新的なIT企業がなぜ民主的なアプリケーション開発にむしろ障害を置くのか」という疑問について、Disney元CEOのMichael Eisnerの言葉を引きつつ、結局のところ企業の本質は利益追求であり、Appleは革新的でも民主的でもなく、収益志向の会社だと主張。より多くの利益が保証されない限り、開発者の参入障壁を下げたり民主的に開放したりすることは、公式ストアという“金のガチョウ”の利益を手放すことになる、つまり利益最優先の論理だという強調
  • オフライン音楽ライブラリを持つAndroidユーザーには Musicolet を強く推奨。完璧に動作するとのこと
    • Plex、Jellyfin、WebDAV、SMBなど幅広い対応が可能なSymfoniumも非常に優れていると強調
  • 掘り下げた技術分析を楽しく読んだという感想。React NativeからSwiftUIへ移行すると、ネイティブコードではiCloudアクセスや最適化がどれだけ簡単になるかを実感したとのこと。SQLite FTS5の検索テクニックも印象的で、自分のライブラリアプリの参考にしたいという
  • 最初はSwiftが難しく感じて避けていたが、その後async/awaitが追加されて並行処理コードが書きやすくなった、という主張には同意しないという意見。asyncはコードを書くうえでは便利だが、規模が大きくなるとコードの流れや並行性の把握がはるかに難しくなる経験をしたという。未解決の問題があるならgreen lightweight threadsのような代替もあり得ると考えており、長期的にはasyncベースの方がむしろ保守コストを上げる可能性があると懸念
    • 問題は並行処理という概念そのものより、async/awaitという抽象化の限界の方だと思うという見方。良い並行処理とは、コードが拡張されても理解しやすく管理しやすいものであるべきで、プロセス/サービス中心のカプセル化には大きな利点があるとの考え
    • 自分のようなシンプルな音楽プレーヤー用途であれば、asyncによる複雑さの増加はほとんど問題にならないだろうとの補足