Pemutar audio yang saya buat sendiri
(nexo.sh)- Berawal dari masalah bahwa bahkan pada 2025 pun masih sulit bagi pengguna untuk bebas mendengarkan dan menyinkronkan file musik yang mereka miliki di iPhone, saya mengimplementasikan sendiri pemutar musik yang mengutamakan lokal dengan SwiftUI
- Jika berhenti berlangganan Apple Music, sinkronisasi iCloud Music Library berhenti; iTunes Match adalah opsi berbayar terpisah seharga $24,99 per tahun yang menyimpan salinan AAC 256 kbps secara online
- React Native/Expo sering gagal atau crash saat menelusuri folder iCloud yang sangat bersarang dan menangani izin file, sehingga implementasi SwiftUI yang memakai API native Apple menjadi pilihan yang lebih sederhana
- Aplikasi ini memakai SQLite FTS5 untuk mencari nama file dan metadata seperti artist, album, title, serta memisahkan impor iCloud, pengelolaan library, dan layar pemutaran
- Karena iOS memiliki batasan security-scoped bookmark dan build pengembangan pribadi, bahkan dalam proses memakai aplikasi buatan sendiri secara stabil untuk jangka panjang pun masih ada hambatan akses file dan distribusi
Mengapa saya membuat pemutar musik sendiri
- Untuk memutar file musik yang dimiliki pengguna di iPhone, masih ada situasi di mana pengguna harus membayar Apple atau mengakali berbagai batasan
- Bagi pengguna yang sudah menata library musik lokalnya, layanan streaming lebih mirip fitur kenyamanan daripada sesuatu yang wajib
- Jika langganan Apple Music dihentikan, sinkronisasi antarperangkat berbasis iCloud Music Library ikut terhenti
- Fitur ini berada di balik langganan
- Dengan memakai iTunes Match, fitur tersebut bisa dipakai lagi seharga $24,99 per tahun
- Match menyimpan salinan AAC 256 kbps secara online, sementara file asli tetap seperti semula selama pengguna tidak mengubahnya
- Tanpa langganan, sinkronisasi cloud hilang dan pengguna harus kembali ke sinkronisasi lewat kabel/Wi‑Fi
- Tujuannya adalah membuat sendiri pemutar musik dasar untuk mengimpor, menata, dan memutar file audio
- Aplikasi yang selesai dibuat menyediakan pencarian teks penuh, dukungan iCloud, dan pengalaman yang mengutamakan lokal, serta dipublikasikan di GitHub
Mengapa pilihan yang ada tidak cocok
-
Aplikasi bawaan Apple
- Dengan aplikasi Files, file musik di iCloud memang bisa diputar langsung, tetapi aplikasi itu tidak dirancang sebagai aplikasi untuk mendengarkan musik
- Fitur inti seperti pengelolaan playlist, pengurutan metadata, dan antrean pemutaran tidak tersedia
- Pemutaran musiknya sendiri memungkinkan, tetapi keseluruhan pengalaman pengguna terbatas, dan ada juga diskusi terkait di komunitas Apple
-
Aplikasi pihak ketiga
- Di App Store ada banyak aplikasi pemutar musik offline, tetapi banyak yang menerapkan harga berbasis langganan bahkan untuk aplikasi yang memutar file yang sudah dimiliki pengguna
- Doppler punya kelebihan berupa model pembayaran sekali beli
- Namun UX-nya berfokus pada pengelolaan album, kualitas pencariannya kurang memuaskan, dan impor dari iCloud dengan banyak folder bersarang terasa lambat serta sulit digunakan
Proses beralih dari React Native ke SwiftUI
-
React Native/Expo sebagai pilihan awal
- Karena pengalaman lama dengan Swift, saya menghindari Swift dan lebih dulu memilih React Native/Expo agar bisa memakai kembali pengalaman pengembangan web
- Implementasi UI pemutaran mudah, dan saya memakai template music-player dari Gionatha Sturba yang tampak memiliki fitur yang diperlukan
- Masalah membesar pada akses sistem file dan sinkronisasi file cloud
- Library seperti
expo-filesystemmendukung pemilihan file dasar, tetapi penelusuran rekursif atas direktori iCloud yang sangat bersarang sering gagal atau membuat aplikasi crash - Sandbox iOS mencegah aplikasi membaca file tanpa izin eksplisit dari pengguna
- Akibatnya, pendekatan berbasis JavaScript menjadi lebih rumit dibanding memakai API native Apple secara langsung; beralih ke Swift memungkinkan kontrol yang lebih baik atas akses file iCloud dan izin sandbox
-
Mengapa memilih SwiftUI
- Alih-alih UIKit atau storyboard, saya memilih SwiftUI untuk membuat lapisan UI deklaratif dan fokus pada logika domain serta sinkronisasi data
- Integrasi
async/awaitSwift dan Swift Actors mempermudah pengelolaan alur data dan concurrency - SwiftUI membantu menyusun aplikasi menjadi komponen ViewModel yang independen
- LLM seperti OpenAI o1 dan DeepSeek menghasilkan lebih sedikit ketergantungan silang yang kompleks saat membuat kode UI murni atau kode data binding
Struktur aplikasi dan model data
-
Tiga layar utama
- Aplikasi dibagi menjadi tiga alur: Library import, Library management, dan Player and playback
- Library import menambahkan folder library iCloud, memindai file audio dari semua folder, lalu memasukkan path ke database SQLite
- Library management mengelola lagu yang telah ditambahkan dan menyusun playlist
- Player and playback menangani repeat, shuffle, pengelolaan antrean, serta fungsi putar, berhenti, dan lagu berikutnya
- File picker bawaan Apple tidak cocok untuk alur memilih banyak direktori dan banyak file sekaligus berdasarkan pencarian kata kunci
- Saat aplikasi dijalankan dengan library kosong, tab Sync menampilkan tombol “Add iCloud Source”
- Setelah folder dipilih, progress bar ditampilkan selama penelusuran tree, lalu setelah indexing selesai aplikasi berpindah ke tab Library
- Layar pertama menampilkan Playlists / Artists / Albums / Songs
- Saat track diketuk, Mini-Player muncul di bagian bawah; mengetuknya membuka Player layar penuh
- Player layar penuh menyediakan shuffle, repeat, pengurutan ulang antrean, dan volume
- Jika menekan “+” di Sync untuk memilih folder lain, lagu baru digabungkan di background tanpa perlu restart
-
Lapisan logika bergaya server
- Meski ini aplikasi mobile, saya menerapkan arsitektur bergaya backend berdasarkan pengalaman dengan backend web dan cloud
- Lapisan domain dan logika dipisahkan dari lapisan View dan ViewModel agar sinkronisasi cloud, parsing metadata, dan akses data SQLite bisa ditangani secara stabil
- Struktur lapisannya adalah sebagai berikut
- SQLite menyimpan baris lagu mentah dan indeks FTS
- Repository membungkus database dan mengekspos API asinkron
- Domain Actor memiliki aturan bisnis seperti impor, pencarian, dan logika antrean
- ViewModel berlangganan ke Actor dan mengubah data menjadi struct untuk UI
- SwiftUI View merender data yang diterima
- Perubahan state dijaga agar thread-safe, dan sinkronisasi iCloud, pemutaran, serta UI dipisahkan agar tidak melompati lapisan secara langsung
Pencarian lokal dengan SQLite FTS5
- Untuk penyimpanan persisten, saya memakai SQLite dan tidak memakai CoreData
- Alasan menghindari CoreData adalah kebutuhan untuk mengontrol sendiri skema, query mentah, dan terutama pencarian teks penuh
- Sejak sekitar iOS 11, SQLite dengan fitur FTS dapat digunakan tanpa konfigurasi tambahan
- Untuk query umum saya memakai SQLite.swift, tetapi query FTS ditangani dengan pernyataan SQL biasa
- SQLite FTS5 memungkinkan query terhadap nama file dan metadata seperti artist, album, title tanpa infrastruktur pencarian terpisah
-
Konfigurasi tabel FTS
- Ada dua tabel FTS5 yang digunakan
songs_fts: digunakan olehSQLiteSongRepositorydan mengindeksartist,title,album,albumArtistsource_paths_fts: digunakan olehSQLiteSourcePathSearchRepositorydan mengindeksfullPath,fileName- Kedua tabel FTS berada berdampingan dengan tabel B-tree dasar, yaitu
songsdansource_paths - FTS bersifat read-only dari UI, dan semua penulisan ditangani di dalam Repository
- Contoh pembuatan
songs_ftsmenempatkansongIdsebagaiUNINDEXEDdan menggunakan tokenizerunicode61 unicode61dipilih untuk menangani berbagai karakter- Key yang tidak dicari ditandai
UNINDEXEDagar kamus istilah tidak membesar tanpa perlu
-
Pencarian parsial dan pemeringkatan
- Saat pengguna mengetik “lumine”, secara internal wildcard ditambahkan seperti “lumine*” untuk segera menemukan hasil pencarian parsial
- Untuk pengurutan hasil pencarian, digunakan
bm25dari SQLite - Cara ini menyediakan skema yang bisa diprediksi, pendekatan local-first, dan pencarian teks penuh yang kuat tanpa menambah ketergantungan jaringan atau layanan eksternal
Akses file iOS dan batasan bookmark
- Aplikasi iOS dapat menyimpan bookmark persisten untuk mengingat lokasi file
- Namun security-scoped bookmarks yang memberi akses diperluas ke file di luar sandbox aplikasi hanya tersedia di macOS
- Aplikasi iOS dapat mengingat path file dengan bookmark biasa dan meminta akses lagi melalui document picker, tetapi tidak ada jaminan bahwa akses tersebut akan terus dipertahankan secara diam-diam
- Penjelasan terkait ada di dokumentasi bookmark Apple
- Untuk memitigasi hal ini, saya mengimplementasikan mekanisme alternatif yang menyalin file ke kontainer sandbox aplikasi itu sendiri
- Selama bookmark masih valid, file disalin secara proaktif di background
- Ini mengurangi risiko mengakses referensi file audio yang tidak valid ketika iOS mereset izin
- Pendekatan ini juga meningkatkan kecepatan indexing
- Struktur folder dipindai sekali selama akses aktif
- Hanya file audio terkait yang diimpor
- Direktori yang sangat bersarang dapat ditelusuri dengan aman
- Masalah memutar file audio individual dari lokasi eksternal secara stabil setelah perangkat restart belum terselesaikan
- Bahkan pada aplikasi native, kasus penggunaan ini belum didukung dengan memadai di iOS, dan menangani akses file secara stabil masih kompleks
Implementasi pemutaran dan UI
-
Parsing metadata
- Untuk parsing metadata file audio, saya memakai
AVURLAssetdari framework Apple AVFoundation AVURLAssetdapat memeriksa metadata file media seperti title dan album artist- Beberapa field seperti nomor track harus dicari langsung dari tag ID3
- Karena dokumentasi resmi tidak cukup mencakup edge case, saya merujuk contoh implementasi lewat pencarian GitHub
- Untuk parsing metadata file audio, saya memakai
-
Pemutaran audio
- Setelah library diindeks, pemutar audio diimplementasikan dengan menginisialisasi instance
AVAudioPlayerlalu memutarnya - Untuk mengontrol musik dari Control Center, protokol
AVAudioPlayerDelegateharus diimplementasikan dan dihubungkan keMPRemoteCommandCenterApple MPRemoteCommandCentermemungkinkan aplikasi merespons kontrol pemutaran tingkat sistem
- Setelah library diindeks, pemutar audio diimplementasikan dengan menginisialisasi instance
Pengalaman pengembangan Swift dan Apple
-
Hal yang sulit
- Preview SwiftUI real-time di Xcode adalah kemajuan, tetapi pengalaman pengembangan keseluruhannya belum mencapai level integrasi VSCode, reload simulator real-time, dan alat debugging familier yang sudah ditawarkan Flutter lima tahun lalu
- Dukungan LSP Swift untuk Neovim atau VSCode membutuhkan alat tambahan seperti
xcode-build-server, dan tidak sama dengan pengalaman pengembangan ekosistem yang berpusat pada web - Sebagian Apple SDK masih bergaya Objective-C
- Pencarian file Spotlight hanya diekspos lewat
NSMetadataQuery, danNSMetadataQuerymemakai KVO serta key string - Belum ada wrapper yang ramah Swift
- UI deklaratif SwiftUI berguna, tetapi perilaku aplikasi penuh yang melibatkan izin iCloud tidak bisa diemulasikan di preview, sehingga interaksi cloud harus dimock secara langsung
-
Hal yang baik
- Berkat
async/await, kode concurrency yang berpusat pada I/O bisa ditulis seperti kode imperatif tanpa callback - Kode sinkron pun mudah dimasukkan ke dalam Actor dan dipanggil seperti di ekosistem JavaScript
- Saya dapat memakai library native Apple secara langsung, tanpa dibatasi binding open source React Native atau Flutter
- Banyak API Apple memiliki contoh sehingga mudah untuk mulai digunakan
- Cara SwiftUI menyusun UI ala React memberi produktivitas dan ruang eksplorasi
- Berkat
Sulitnya memakai aplikasi pribadi dalam jangka panjang di iOS
- Setelah sekitar 1,5 minggu implementasi, saya berhasil membuat pemutar musik lokal/offline yang dapat mengimpor file audio dari penyimpanan iCloud
- Namun tanpa sertifikat developer, aplikasi hanya berjalan selama 7 hari, lalu harus dibuild lagi
- Untuk mendaftar Apple Developer Program, pengguna harus membayar $99
- Bahkan setelah DMA Act di UE, sideloading belum sepenuhnya terbuka
- Pengguna UE dapat menginstal aplikasi marketplace pihak ketiga dari situs developer
- Developer tetap harus terdaftar di program Apple senilai $99/tahun
- Developer juga harus menyetujui Alternative Terms dari Apple
- Untuk penggunaan pribadi atau hobi, batasan build pengembangan 7 hari tidak hilang
- PWA di iOS juga masih memiliki batasan
- Bahkan setelah pembaruan iOS 16 hingga 18.x, PWA berjalan di dalam sandbox Safari
- WebGL2 dan web-push dapat digunakan
- Web Bluetooth, USB, NFC, Background Sync, serta penyimpanan terjamin di atas sekitar 50 MB tidak disediakan
- Karena WebGL melewati Metal shim, frame rate aktualnya sering tertinggal dibanding aplikasi Metal native
- AI menurunkan kompleksitas pengembangan software dengan membuat pengetahuan yang dibutuhkan untuk menangani teknologi yang belum familier menjadi lebih mudah diakses, tetapi aplikasi iOS tetap harus mengikuti aturan artifisial
- Bahkan untuk aplikasi yang dibuat sendiri oleh individu, masih ada rintangan terakhir dari Apple jika ingin menjalankannya lebih dari seminggu, dan ini membatasi pengembangan serta distribusi aplikasi pribadi
1 komentar
Komentar Hacker News
Saya melewati masa ketika Winamp adalah pemutar musik bawaan, dan bahkan di era streaming saya masih menata perpustakaan musik lokal saya dalam folder
Seperti orang lain di komentar ini, saya membuat pemutar musik jadul sebagai proyek hobi untuk mendengarkan musik secara offline; ini adalah aplikasi HTML/JS satu halaman dengan kontrol keyboard penuh dan fitur antrean sederhana
Bisa dilihat di sini: https://nobsutils.com/mp
Saya menyukai kesederhanaannya: kumpulan file dalam direktori, acak seluruh koleksi, atau memutar hanya direktori tertentu
Sebagai catatan, shortcut bookmark standar saat ini
cmd + dmengubah tema alih-alih menandai situsSaya membangun koleksi musik selama 25 tahun dalam format FLAC, dan tahun lalu membeli ponsel Android serta kartu MicroSD 1TB sehingga akhirnya bisa memuat semua musik saya
Ini proyek panjang sampai teknologinya bisa mengejar, tetapi sekarang semuanya bisa masuk ke saku saya dan itu terasa sangat memuaskan
Rasanya saya tidak mungkin satu-satunya orang yang tidak ingin menjadi penyewa yang menyerahkan kendali sambil menoleransi iklan dan men-streaming apa pun yang dipaksakan industri, dan keren juga melihat orang sampai membuat aplikasinya sendiri
Dengan re-encode yang baik, semua musik bisa dimuat di kartu yang jauh lebih kecil dengan kualitas transparan yang perbedaannya tidak akan terdengar, sementara FLAC bisa disimpan di desktop sebagai cadangan
Koleksi saya hanya sekitar 25% FLAC/APE/ALAC/WavePack, tetapi tetap lebih dari 3TB, jadi sulit mendengarkan musik saat bepergian
Saya tidak bisa memilih lebih dulu apa yang akan dimasukkan ke perangkat seluler
Kombinasi server https://www.navidrome.org dan klien https://symfonium.app sangat bagus bagi saya
Sekarang sudah ada kartu SD 2TB juga, jadi mungkin saya akan membelinya saat harganya turun
Kadang perubahan tidak diterapkan, atau sempat diterapkan lalu tiba-tiba berubah menjadi sampul yang salah, dan kelihatannya seperti bug Android
Penasaran apakah Anda juga pernah mengalami masalah seperti ini
Saya membuat aplikasi web sendiri agar bisa mendengarkan album penuh sambil tetap bisa berhenti di tengah atau berpindah perangkat
Saya suka mendengarkan album dari awal sampai akhir, tetapi setidaknya YouTube Music tidak mengingat posisi putar, jadi di perangkat lain saya harus membuka album yang sama lagi dan mencari titik tempat saya berhenti
Aplikasi web saya bisa menerima URL, mengunduhnya di server dengan
yt-dlp, lalu men-streaming dari sana, dan selalu mengingat posisi putar sehingga saya bisa mendengarkannya di ponsel saat di mobil lalu melanjutkan di laptop saat di kantorIni juga cocok saat menambahkan mix dari sumber lain seperti NTS Radio
Kalau aplikasi web itu tersedia untuk umum, saya ingin melihatnya
Saya belum selesai membaca semuanya, tetapi ini tulisan yang bagus, dan saya suka membaca bagaimana pengembang mengambil keputusan yang lebih rinci dan alasannya
Saya sangat paham dengan perasaan bahwa pemutar audio yang sudah dicoba tidak ada yang memuaskan
Di dunia aplikasi musik, tata letak layar dan UI tampaknya hampir sudah menjadi hal yang universal, tetapi saya tidak menyukainya dan juga kurang mengerti kenapa harus begitu
Rasanya seperti harus bertinju dengan semua aplikasi musik, jadi menyenangkan melihat orang yang mencoba membuat sesuatu yang baru
Saya masih memakai aplikasi Apple Music untuk file lokal saya
Layanan streaming Apple Music saya nonaktifkan, lalu semuanya saya impor ke aplikasi Apple Music di macOS, setelah itu saya colokkan ponsel ke laptop dan sinkronkan seperti iPod di tahun 2007
Semuanya berjalan persis seperti yang saya harapkan, dan karena musik saya tidak sering berubah, sinkronisasi juga bukan masalah
Ada rasa nostalgia yang aneh juga saat sinkronisasi lewat kabel
Saya sulit setuju dengan anggapan bahwa pada masa sebelum ada
async/await, kode konkurensi di Swift terasa lebih kikuk dan penuh boilerplate dibanding Go atau JS/TSPemrosesan asinkron memang bisa membuat penulisan kode konkurensi lebih mudah, tetapi ketika codebase membesar, penalarannya bisa menjadi kurang sederhana
Dalam codebase asinkron yang kompleks, lebih sulit memahami alur kode dan konkurensinya
Jika tujuannya adalah menurunkan biaya eksekusi kode thread, ada solusi berupa green thread ringan, dan jika tujuannya menurunkan biaya pemeliharaan kode thread, pendekatan async kemungkinan justru menuntut lebih banyak usaha dalam jangka panjang
Enkapsulasi berbasis proses atau layanan saja sudah memberi keuntungan besar
Menurut saya ini bukan kegagalan konkurensi itu sendiri, melainkan lebih merupakan keterbatasan abstraksi async/await
Saya tadinya berharap tulisan ini membahas bukan hanya perangkat lunak untuk mengelola dan memutar lagu, tetapi juga perangkat fisik
Beberapa tahun lalu saya ingin membelikan pemutar MP3 untuk anak saya yang berusia 10 tahun, yang sangat suka mendengarkan musik tetapi belum siap memakai ponsel, dan saya kaget karena pilihannya sangat menyedihkan
Menurut saya, ketika Apple menghentikan iPod, tercipta kekosongan besar yang tidak pernah benar-benar diisi siapa pun
iPod shuffle berbentuk USB stick adalah pemutar MP3 terbaik yang pernah saya pakai; kecil, bisa langsung dicolok tanpa kabel terpisah, dan baterainya juga tahan lama
Tidak ada layar untuk menelusuri musik, tetapi memang itu tujuannya, jadi cukup serahkan pada mode acak
Sangat disayangkan bahwa bahkan konsep yang relatif sederhana seperti ini pun tidak pernah benar-benar berhasil ditiru di pasar perangkat keras
Orang-orang mungkin akan bilang ini bukan masalah perangkat keras melainkan masalah perangkat lunak/DRM, tetapi tetap saja sangat disayangkan bahwa tidak ada perangkat pemutar musik portabel murah yang bagus
Kehadiran Spotify dan smartphone-lah yang membunuh pemutar MP3, dan keduanya mengambil terlalu banyak ruang di pasar hingga yang lain mati tercekik
Misalnya ada https://www.fiio.com/cp13 dan https://www.fiio.com/jm21
Ini juga cocok sebagai proyek edukasi kecil untuk belajar elektronika dan mendaur ulang perangkat “lama”
Ada banyak pilihan kustomisasi tampilan, dan modifikasi yang lebih dalam seperti menambahkan Bluetooth atau USB‑C juga memungkinkan
Seperti yang dikatakan orang lain, sisi perangkat lunaknya juga masih berjalan baik lewat iTunes di Windows serta integrasi Finder/Music di macOS
Pabrikan Tiongkok menjual perangkat seharga 50~100 dolar yang terlihat bagus, bisa memutar musik, dan juga punya fungsi smartphone, seperti Mini iPhone 16 atau Mini S24
Para orang tua kemungkinan besar akan membelikan perangkat semacam itu untuk anak mereka alih-alih pemutar MP3
Tidak memberi ponsel kepada anak laki-laki berusia 14 tahun adalah gaya pengasuhan yang tidak lazim namun saya hormati, tetapi tampaknya permintaan seperti itu saat ini tidak lebih besar daripada pasokan yang tersedia
Mungkin terlalu mahal untuk anak 10 tahun, tetapi mungkin Anda bisa menemukan unit bekas di eBay
Kombinasi mengelola musik lokal dengan Music.app dan memakai sinkronisasi iPhone lewat Finder masih cocok untuk saya
Hanya saja, Music.app terasa seperti tidak dirawat selama bertahun-tahun sejak penulisan ulang Big Sur yang buruk itu, dan ada bug yang menjengkelkan
Terlepas dari kekurangannya, kombinasi ini adalah solusi manajemen perpustakaan musik + sinkronisasi seluler terbaik yang pernah saya lihat, tetapi karena perangkat lunaknya tidak dirawat dan juga tidak lintas platform, pada akhirnya saya merasa harus memakai sistem buatan sendiri
Banyak keanehan khas iTunes yang masih tersisa, seperti jendela pengaturan/preferensi modal yang merupakan peninggalan era OS 9
Jendela pengaturan di OS X seharusnya tidak modal
Saya menduga mereka sedang mengerjakan versi yang benar-benar dibuat ulang dari nol secara internal, seperti Music untuk Windows berbasis WinUI yang sepenuhnya baru
Yang paling menyebalkan adalah sinkronisasi podcast; dulu semuanya baik-baik saja saat ditangani iTunes, tetapi sinkronisasi Finder di Big Sur punya bug sehingga jika berpindah ke trek atau podcast lain lalu kembali, posisi pemutaran tidak diingat
Akibatnya, podcast yang lebih panjang dari beberapa menit praktis sulit dipakai di perangkat itu
Alih-alih pindah ke Android, orang-orang benar-benar sampai membuat aplikasi musik mereka sendiri
Saya penasaran apakah ini karena gelembung chat biru, atau karena semua hal “langsung bekerja”, kecuali pemutaran musik offline
Saya tidak paham apa masalahnya kalau memanggang sendiri
Alasannya, aplikasi VLC tidak bisa secara andal mem-parsing metadata FLAC yang ada di server file saya, dan karena batasan penyimpanan, saya juga tidak bisa menyimpan seluruh koleksi musik di perangkat
Aplikasi saya memang masih prototipe karena saya ingin lebih banyak fitur, tetapi sudah memiliki pemutaran audio, akses file jarak jauh, dan parsing metadata FLAC, jadi sudah cukup berfungsi sampai saya kurang termotivasi untuk menambahkan fitur lain
Seperti penulis, awalnya saya ingin memakai React Native karena saya sudah berpengalaman dan juga punya beberapa aplikasi yang sedang dirawat, tetapi saya tidak ingin menargetkan platform lain atau melakukan debugging untuk itu
Jadi saya memutuskan mencoba SwiftUI, dan dengan alat khusus[1] saya membuat sesuatu yang mirip hot reload
Ini memang hack yang cukup kotor karena harus memasukkan linker flag kustom ke Xcode, tetapi cukup berfungsi sehingga saya tidak terlalu merindukan pengalaman pengembang TypeScript dan React Native
[1] https://github.com/johnno1962/InjectionIII
Sebenarnya saya agak merasa aneh bahwa penulis tidak bisa menemukan aplikasi musik gratis yang dia sukai
Meski begitu, orang tidak harus punya alasan yang sangat kuat untuk membuat sesuatu, jadi mungkin itu hanya narasi untuk memulai cerita
Musik yang dipilih juga bisa disimpan di perangkat
Jika punya koleksi musik offline, saya sangat merekomendasikan https://play.google.com/store/apps/details?id=in.krosbits.mu...
Berfungsi dengan baik tanpa masalah
Mendukung Plex, Jellyfin, WebDAV, SMB, dan lainnya