365 bacaan
365 bacaan

Pada tahun 2025, muzik tempatan pada iPhone adalah mimpi buruk - jadi saya membina jalan saya sendiri

oleh Oleg Pustovit12m2025/05/22
Read on Terminal Reader

Terlalu panjang; Untuk membaca

Pada tahun 2025, memainkan muzik anda sendiri pada iPhone sangat sukar, melainkan anda membayar Apple atau menavigasi labirin batasan.
featured image - Pada tahun 2025, muzik tempatan pada iPhone adalah mimpi buruk - jadi saya membina jalan saya sendiri
Oleg Pustovit HackerNoon profile picture
0-item

Pada tahun 2025, memainkan muzik anda sendiri pada iPhone adalah mengejutkan sukar, melainkan anda membayar Apple atau menavigasi labirin batasan. jadi saya membina pemain saya sendiri dari awal, dengan carian teks penuh, sokongan iCloud, dan pengalaman lokal pertama.

Pada tahun 2025, bermain anda sendirimusic on an iPhone is surprisingly hard, melainkan anda membayar Apple atau menavigasi labirin batasan. jadi saya membina pemain saya sendiri dari awal, denganfull text searchdaripadaiCloud supportdan alocal-first experiencedaripadaRangkaian GitHub

Mengapa saya membina pemutar audio saya sendiri

Seperti banyak orang, saya telah mengambil terlalu banyak langganan, beberapa melalui Apple (iCloud, Apple Music), yang lain hilang dalam platform acak (seperti Netflix, yang saya lupa saya masih membayar).

Awalnya saya fikir, saya hanya akan terus menggunakan Perpustakaan Muzik iCloud untuk penyegerakan muzik antara peranti, tetapi sebaik sahaja saya membatalkan langganan Apple Music, penyegerakan berhenti berfungsi.behind a paywallAnda boleh mengembalikannya secara teknikal melaluiPerlawanan iTunes($ 24.99 setiap tahun)Match hanya menyimpan salinan AAC 256-kbps dalam talian; fail asal anda kekal ditempatkan kecuali anda memilih untuk menggantikan mereka. Pada Mac moden, anda melakukan semua ini dalam aplikasi Muzik.

Perlawanan iTunes

Kecewa dengan kekurangan pilihan, saya pergi kebuilder routeJika saya membeli peranti pengkomputeran (iPhone dalam kes ini), apa yang menghalang saya daripada hanya membina apa yang saya perlukan dengan kod untuk menggunakannya? dalam artikel ini, saya ingin berkongsi perjalanan penuh frustrasi saya ke arah mewujudkan fungsi pemutar muzik asas: memuat naik fail audio, mengatur dan memainkan mereka semula, tetapi terutamanya, saya ingin mengingatkan diri saya,ini masih sebuah komputer tujuan umum, saya perlu dapat membuatnya melakukan apa yang saya mahu.

Apa yang Apple (dan lain-lain) menawarkan hari ini

Sebelum menulis aplikasi saya sendiri, saya meneroka pilihan rasmi dan pihak ketiga untuk memainkan muzik di luar talian.

Aplikasi Built-in Apple

Apple secara teknikal membolehkan anda memainkan muzik terus daripada iCloud melalui aplikasi Fail, tetapi fungsinya tidak direka untuk mendengarkan muzik.lacks essential featuresseperti pengurusan senarai main, pemasangan metadata, atau barisan main. Walaupun ia menyokong pemutaran muzik, ia sangat terhad dan keseluruhanTiada pengalaman pengguna yang baik.

Tiada pengalaman pengguna yang baik

Aplikasi Pihak Ketiga

Saya pergi ke kedai aplikasi untuk mencari aplikasi keren yang menyelesaikan masalah saya, manakala terdapat banyak daripada mereka, ramai bergantung kepadasubscription-based pricing, model yang dipertanyakan untuk aplikasi yang hanya memainkan fail pengguna yang sudah mempunyai.Doppler yangSaya telah bermain dengannya semasa percubaan, tetapi UX dibina di sekitar menguruskan album. Pencarian tidak begitu baik, dan fungsi import daripada iCloud lambat dan sukar untuk digunakan pada sejumlah besar folder yang diikat.

Going Builder Mode: Perjalanan Teknikal Saya

Dengan itu dikatakan, saya memutuskan untuk mencipta pemutar muzik ideal saya sendiri yang menyelesaikan kesakitan saya:

  • Penyelidikan teks penuh yang fleksibel di seluruh folder iCloud, supaya saya boleh memilih dan mengimport folder dengan muzik atau fail tertentu dengan cepat.
  • Fungsi dalam menguruskan muzik sekurang-kurangnya sama dengan App Music rasmi: barisan, pengurusan playlist, dan pemasangan mengikut album, dan lain-lain.
  • Antara muka yang akrab dan mesra.

Cuba React Native Pertama

Beberapa tahun yang lalu, saya suka sintaks (merasa lebih dekat dengan TypeScript) dan menghargai keselamatan memori seperti Rust, tetapi tanpa asliasync/awaitPada masa itu, menulis kod simultan berbanding dengan Go atau JS / TS terasa klunky dan boilerplate-berat. pengalaman itu meninggalkan saya kecewa, jadi apabila saya melihat semula projek ini, saya mula-mula menjangkau sesuatu yang lebih akrab.

Yang mengatakan, saya pergi dengan React Native atau Expo, berharap untuk menggunakan semula pengalaman pembangunan web saya dan menyambungkan UI pemain dari templat sedia ada. Membina UI main adalah mudah; terdapat banyak contoh sumber terbuka dan video tutorial tentang membina pemutar muzik yang kelihatan baik yang sesuai dengan keperluan saya.Projek template oleh Gionatha Sturba, kerana ia kelihatan mempunyai semua ciri yang saya perlukan untuk app saya.

Attempting to build an app with React Native/Expo

Mengakses sistem fail dan menyegerakkan fail awan menjejaskan jalan utama: perpustakaan sepertiexpo-filesystemdisokong pemilihan fail asas, tetapi traversal recursive di atas direktori iCloud yang tertanam dalamoften failed or even caused app crashesIni menjadikan jelas bahawa aJavaScript-based approach introduced more complexitydaripada hanya bekerja dengan API asli Apple, walaupun ia bermakna kurva pembelajaran yang lebih tajam.

Sandboxing iOS menghalang aplikasi daripada membaca fail tanpa kebenaran pengguna yang jelas, yang bermakna React Native tidak boleh mengakses folder luaran dengan boleh dipercayai.

Menukar kepada SwiftUI

Saya pergi denganSwiftUIdaripada UIKit atau storyboards kerana saya mahuclean and declarative UIlapisan yang akan terlepas daripada jalan sementara saya memberi tumpuan kepada logik domain dan penyegerakan data.Dengan ciri-ciri moden seperti async/await dan integrasi denganSwift Actors, Saya mendapati ia lebih mudah untuk menguruskan aliran data dan keserasian. SwiftUI juga pasti menjadikan ia lebih mudah untuk membina aplikasi ke dalam komponen ViewModel yang terpencil, yang pada gilirannya membantu saya mendapatkan hasil yang lebih baik daripada LLM seperti OpenAI o1 dan DeepSeek. LLM boleh menghasilkan kod UI tulen atau kod pengikat data tanpa memperkenalkan saling ketergantungan yang membingungkan.

Arsitektur App dan Model Data

Mari kita pergi ke atas seni bina aplikasi yang saya cipta: saya menggunakan SQLite untuk penyimpanan data yang berterusan dan mendekati seni bina aplikasi sebagai aplikasi pelayan yang mudah. saya mengelakkan CoreData kerana saya memerlukan kawalan yang ketat atas skim, pertanyaan mentah, dan terutamanya carian teks penuh. sokongan FTS5 built-in SQLite membolehkan saya menambah carian yang cepat tanpa menarik dalam enjin carian luaran yang berat atau membina lapisan indeks saya sendiri.

Tiga skrin utama

The app consists of 3 screen/modes:

  1. Di sini anda menambah folder perpustakaan iCloud anda. Aplikasi ini memindai setiap folder untuk fail audio dan memasukkan setiap laluan ke dalam pangkalan data SQLite. Dengan cara ini, anda boleh mempunyai fleksibiliti penuh dalam mencari, menambah folder, dan subfolders. pemilih fail asli Apple sangat mudah; anda tidak boleh memilih pelbagai direktori yang anda carian mengikut kata kunci dan kemudian juga sekumpulan fail dalam satu langkah.
  2. Pengurusan perpustakaan. Di sini anda boleh menguruskan lagu-lagu yang ditambahkan dan mengatur senarai main.Sebagian besar, saya telah mencerminkan cara Apple melakukannya dalam aplikasi Muzik mereka, dan ia cukup baik untuk keperluan saya.
  3. Bahagian ini daripada aplikasi menguruskan pengurusan barisan (repeat, shuffle), dan lain-lain, dan memainkan, berhenti, dan fungsi lagu seterusnya.

Sebuah diagram aliran pengguna mudah dipaparkan di sini:

User flow diagram

User flow in practice:Apabila aplikasi dilancarkan dengan pustaka kosong, ia mendarat pada tab Sinkronisasi, menunjukkan butang besar "Tambah Sumber iCloud". Pilih folder di sana, dan skrin Sinkronisasi memaparkan bar kemajuan semasa ia berjalan pokok. Sebaik sahaja pengindeksan berakhir, ia menukar anda ke tab pustaka, yang senarai skrin pertamaPlaylists / Artists / Albums / SongsTenggelamkan ke dalam mana-mana senarai, ketuk trek, dan Mini-Pemain muncul di sepanjang bahagian bawah; ketuk mini-bar itu untuk membuka pemutar skrin penuh dengan shuffle, repeat, baris semula, dan volume. Tukar atau ketuk ikon tutup, dan anda langsung kembali ke Perpustakaan semasa pemutaran berterusan. Setiap kali anda memerlukan lebih banyak muzik, melompat semula ke Sinkronisasi, ketik "+" dalam bar nav, pilih folder lain, dan perkhidmatan import menggabungkan lagu-lagu baru di latar belakang, tiada restart diperlukan.

Backend-Like Logic Lapisan

Mempunyai latar belakang web / awan dan menghantar banyak kod pelayan semasa bekerja di startup, saya pergi denganbackend-like architectureuntuk aplikasi mudah alih. keseluruhan domain / lapisan logik telah dipisahkan daripadaView and View-Model layerkerana saya terpaksa menggelengkancloud syncing, metadata parsingaspek aplikasi dan mempunyai akses data yang bersih kepada DB SQLite.Berikut ialah diagram arsitektur berlapis yang saya gunakan di sini:

Layered architecture diagram

How the layers talk:SQLite duduk di bahagian bawah, menyimpan baris lagu mentah dan indeks FTS. Kemudian repositori membungkus pangkalan data dan mendedahkan API async.domain actors, Pemain Swift yang mempunyai semua peraturan perniagaan (import, carian, logik barisan) jadi mutasi keadaan kekalthread-safeViewModels mendaftar kepada pelakon, menukar data kepada struktur bersedia UI, dan pandangan SwiftUI hanya memaparkan apa sahaja yang mereka perolehi.nicely decoupled.

Implementasi Pencarian Teks Lengkap dengan SQLite

Seperti yang saya sebutkan sebelum ini, ia bertuah bahawa anda boleh mengimport versi SQLite dengan keupayaan FTS: bermula sekitar iOS 11, ia boleh didapati di luar kotak.without extra setupIni menjadikan mudah untuk mengintegrasikan carian yang tidak jelas ke dalam perpustakaan muzik saya.without any third-party dependenciesSelain itu, saya menggunakan pustaka SQLite.swift untuk pertanyaan biasa (yang berfungsi sebagai sejenis pembina pertanyaan dengan keselamatan masa kompilasi); Walau bagaimanapun, untuk pertanyaan FTS, saya terpaksa menggunakan pernyataan SQL biasa.

Melayu kepada MelayuFTS5 yangekstensi ini akhirnya menjadi salah satu bahagian yang paling berharga dalam seni bina.Ia membolehkan saya menginterogasi nama fail dan metadata seperti artis, album, dan tajuk tanpa infrastruktur indeks tambahan.

Menubuhkan Jadual FTS

Domain

Swift actor / repo

FTS5 table

Columns that get indexed

Library songs

SQLiteSongRepository

songs_fts

artist, title, album, albumArtist

Source-browser paths

SQLiteSourcePathSearchRepository

source_paths_fts

fullPath, fileName

Lagu Perpustakaan

SQLiteSongRepository

songs_fts

artistdaripadatitledaripadaalbumdaripadaalbumArtist

Sumber-browser laluan

SQLiteSourcePathSearchRepository

source_paths_fts

fullPathdaripadafileName

Saya menggunakan dua jadual FTS5: satu untuk lagu-lagu yang diindeks (artist/title/album) dan satu untuk laluan fail semasa pengimport folder.songsdaripadasource_pathsFTS ialahread-only for the UISemua penulisan berlaku di dalam repositori sehingga tiada apa-apa yang tergelincir melalui retakan.

Mencipta indeks carian

FTS5 built-in SQLite membuat carian cepat mudah. Berikut ialah definisi jadual mudah yang saya gunakan:

try db.execute("""
CREATE VIRTUAL TABLE IF NOT EXISTS songs_fts USING fts5(
  songId UNINDEXED,
  artist, title, album, albumArtist,
  tokenize='unicode61'
);
""")

saya gunakanunicode61Tokenizer untuk memastikan bahawa pelbagai watak dikendalikan. kunci yang tidak boleh dicari ditandai denganUNINDEXEDOleh itu, mereka tidak menghalang perkataan dalam kamus.

Memperbarui data secara boleh dipercayai

Untuk menjaga perkara-perkara mudah dan selamat, saya membungkus kemas kini dan masukkan dalam transaksi. Ini memastikan indeks carian tidak pernah keluar daripada sinkronisasi, walaupun jika aplikasi pecah atau terganggu.

func upsertSong(_ song: Song) async throws {
    db.transaction {
        // insert or update main song data
        // insert or update search index data
    }
}

Mencari dengan Fuzzy Search

Untuk carian yang mudah digunakan, saya menambah sokongan wildcard secara automatik.Jika anda mengetik "lumine", ia mencari "lumine*" secara dalaman, memberikan hasil segera walaupun dengan pertanyaan sebahagian.

Saya juga memanfaatkan SQLite's built-in smart ranking (bm25) untuk mengembalikan hasil yang lebih relevan tanpa kerumitan tambahan:

SELECT s.*
FROM songs s JOIN songs_fts fts ON s.id = fts.songId
WHERE songs_fts MATCH ?
ORDER BY bm25(songs_fts)
LIMIT ? OFFSET ?;

Secara keseluruhan, menggunakan SQLite mentah memberi saya fleksibiliti yang saya perlukan: skim yang dapat diprediksi, akses tempatan pertama, dan carian teks penuh yang berkuasa, tanpa memperkenalkan apa-apa ketergantungan rangkaian atau perkhidmatan luaran.

Bekerja dengan iOS File dan Bookmarks

Pada iOS, aplikasi boleh menyimpan tanda laluan kekal untuk lokasi fail, tetapisecurity-scoped bookmarks, yang memberikan capaian diperluaskan kepada fail di luar sandbox aplikasi, hanya boleh didapati padamacOSAplikasi iOS boleh menggunakan tanda laluan biasa untuk mengingat laluan fail dan meminta capaian semula melalui pemilih dokumen, tetapi capaian itu tidak dijamin kekal diam.Dokumen Bookmark Apple.

Untuk mengurangkan ini, saya mengimplementasikan mekanisme balik yang menyalin fail ke dalamapp's own sandboxed containerIni mengelakkan kitaran hayat yang rapuh daripada tanda laluan keselamatan yang boleh pecah diam-diam jika iOS memulihkan keizinan.Dengan menyalin fail secara proaktif di latar belakang, manakala tanda laluan adalah sah, tiada risiko untuk mengakses rujukan fail audio yang tidak sah.

Pendekatan ini juga meningkatkan kelajuan pengindeksan.Saya boleh memindai struktur folder sekali (selagi akses aktif), mengimport hanya fail audio yang berkaitan, dan dengan selamat melintasi direktori yang tertanam dalam.Tetapi dengan selamat memainkan semula fail audio individu dari lokasi luaran, terutamanya selepas peranti dimulakan semula,kekal masalah tak terpecahkan bagi sayaIni menunjukkan bagaimanaunder-supportedkes penggunaan ini adalah, walaupun untuk aplikasi asli, dan betapa rumitnya ia masihhandle file access reliably on iOS.

Membina Playback dan UI

Metrik Parsing

Untuk menganalisis metadata daripada fail audio, saya menggunakanAVFoundation frameworkSecara khusus, yangAVURLAssetkelas, yang membolehkan pemeriksaan metadata fail media, seperti tajuk, artis album, dan lain-lain manakala pemindaian metadata dikendalikan oleh SDK asli, medan tertentu seperti nombor trek yang anda perlu mencari secara manual daripada tag ID3.Pencarian GitHubuntuk mencari contoh, kerana dokumen rasmi tidak mempunyai penutup untuk kes edge.

Pengeluaran Audio dengan AVFoundation

Selepas perpustakaan diindeks, melaksanakan pemutar audio kelihatan agak mudah: anda hanya perlu memulakan satu contohAVAudioPlayerSelain itu, untuk ciri-ciri kualiti hidup: memainkan muzik dari pusat kawalan, saya terpaksa melaksanakanAVAudioPlayerDelegateProtokol dan juga terhubung ke dalam AppleMPRemoteCommandCenter, yang membolehkan pengembang bertindak balas kepada kawalan pemutaran peringkat sistem.

Refleksi: Apple, Pengembang Lock-In, dan Masa Depan

Berikut ialah apa yang muncul semasa pembangunan:

yang jahat

Xcode's limitations remain frustrating.Preview SwiftUI masa nyata pasti merupakan satu langkah maju, tetapi pengalaman pembangunan keseluruhan masih tidak seimbang dengan apa yang ditawarkan Flutter lima tahun yang lalu: integrasi VSCode yang ketat, muat semula simulator masa nyata, dan alat debugging yang biasa.

Lack of editor flexibility.Menetapkan sokongan Language Server Protocol (LSP) untuk Swift dalam Neovim atau VSCode memerlukan alat tambahan sepertixcode-build-server, dan masih tidak sepenuhnya sepadan dengan pengalaman pengembang ekosistem web pertama.

Some corners of Apple's SDK still live in Objective-C land.Pencarian fail Spotlight, contohnya, hanya dipaparkan melaluiNSMetadataQuery, yang menggunakan Key-Value Observing (KVO) dan kunci string, tidak ada wrapper yang mesra dengan Swift.

SwiftUI's declarative UI is great, but debugging iCloud interactions still requires manual mocks.SwiftUI preview tidak boleh meniru tingkah laku aplikasi penuh yang melibatkan hak-hak iCloud, jadi anda perlu mengejek interaksi awan secara manual, yang sedikit menjengkelkan tetapi penting.

yang baik

Async/await.Akhirnya, saya boleh menulis I / O-bound kod simultan seperti yang penting tanpa panggilan balik yang menjengkelkan.Ini adalah kemenangan besar, dan saya sangat menghargai betapa mudahnya untuk menulis kod sinkron ke dalam Actors dan memanggilnya seperti yang anda lakukan dalam ekosistem JavaScript.

Plethora of native libs.Ya, anda tidak terhad kepada pautan sumber terbuka seperti dalam ekosistem React Native/Flutter. Di sini anda mempunyai kebebasan yang lebih besar dalam membangunkan sesuatu yang "lebih serius" daripada penggantian laman web syarikat / produk anda (karena pengalaman mobile-first yang buruk).

SwiftUIYa, pendekatan gaya React untuk membina UI memberi lebih banyak produktiviti dan ruang untuk meneroka.

Tag: pembinaan lebih mudah

Selepas 1.5 minggu hacking, saya boleh mendapatkan perisian yang memenuhi keperluan saya dengan tepat:local/offline music playeryang boleh mengimport fail audio daripada penyimpanan awan.

Tetapi pengembang cepat menyedari bahawa mereka tidak boleh dengan mudah menyebarkan aplikasi ke peranti mereka sendiri hari ini dan melupakannya: aplikasi hanya berjalan untuk7 days without a dev certificate, dan selepas itu, anda mesti membina semula, melainkan anda membayar $ 99 kepada Apple untuk mendaftar dalam program pembangunan.

7 hari tanpa sijil dev

Walaupun selepasDMA Act in the EUPengguna EU kini boleh memasang aplikasi dari pasaran pihak ketiga terus dari laman web pengembang, tetapi hanya jika pengembang itu masih mendaftar dalam program $ 99 / tahun Apple dan bersetuju dengan Terma Alternatif Apple.

Ini pada akhirnya tidak masuk akal. sebuah syarikat teknologi inovatif secara aktif meletakkan halangan dalam pembangunan aplikasi yang demokratis.Menghadapi batasan yang ketara pada iOS: walaupun selepas kemas kini 16-18.x Apple, PWA iOS masih berjalan di dalam sandbox Safari. Mereka mendapat WebGL2 dan web-push, tetapi mereka tidak mendapat Web Bluetooth / USB / NFC, Background Sync, atau lebih daripada ~50MB penyimpanan yang dijamin. WebGL berjalan melalui Metal shim, jadi kadar bingkai dunia sebenar sering mengikuti aplikasi Metal asli; ini cukup baik untuk UI, tetapi tidak untuk permainan 3D AAA.

Hari ini, AI telah mengurangkan kerumitan pembangunan perisian moden dengan membolehkan sesiapa sahaja untuk menangani teknologi yang tidak diketahui dengan menyediakan semua pengetahuan yang diperlukan dengan cara yang mudah diakses.Anda boleh melihat dengan jelas bagaimana pembangunan web mendapat lebih banyak minat daripada orang-orang non-teknik yang mempunyai cara untuk membina idea mereka tanpa mengkhususkan diri dalam pelbagai teknologi.Tetapi apabila datang kepada aplikasi mudah alih, anda hanya perlu bermain mengikut peraturan buatan.Walaupun anda membina sendiri, untuk diri anda sendiri, Apple masih mendapat ucapan terakhirsebelum anda boleh menjalankan ia selama lebih daripada seminggu. syarikat yang sama yang pernah membolehkan pengembang bebas kini memaksakantight restrictions that hinder personal app developmentAI telah menjadikannya lebih mudah daripada sebelumnya untuk membina alat-alat baru, melainkan anda membina untuk iOS, di mana gerbang masih terkunci.

Links yang berkaitan

  • iTunes Match – Sokongan Apple
  • Pengesahan keselamatan - Apple Docs
  • FTS5 - Dokumentasi SQLite
  • Pemain Muzik Doppler - App Store
  • Dokumentasi FileSystem Expo
  • Maklumat Program Pembangun Apple (7 hari pembinaan)
  • Komuniti Apple: Files App & MP3 Playback


L O A D I N G
. . . comments & more!

About Author

Oleg Pustovit HackerNoon profile picture
Oleg Pustovit@nexo-tech
Startup tech lead with a focus on DevOps, automation, and lean MVP development. Sharing insights from building early-stage products and platforms.

GANTUNG TANDA

ARTIKEL INI DIBENTANGKAN DALAM...

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks
OSZAR »