Saluran Distribusi Lain — Mac App Store
Seri sebelumnya membahas konfigurasi satu kali untuk mendistribusikan aplikasi macOS secara langsung dengan Developer ID. Setelah sertifikat, notarisasi, pembaruan otomatis Sparkle, dan feed pembaruan yang dihosting sudah tersedia, Anda dapat membiarkan pengguna mengunduh file .dmg secara langsung tanpa melalui App Store.
Seri ini membahas konfigurasi satu kali untuk menempatkan aplikasi yang sama di Mac App Store (MAS) juga. Dua metode distribusi ini bukan pilihan yang saling eksklusif. Anda dapat menjalankan satu aplikasi melalui saluran distribusi langsung dan saluran App Store secara bersamaan. App Store memiliki Apple yang menangani pembayaran, pengembalian dana, dan visibilitas pencarian atas nama Anda, serta membawa kepercayaan pengguna yang lebih tinggi, sehingga menjalankannya bersamaan dengan distribusi langsung adalah pilihan yang umum.
Seri ini mengasumsikan aplikasi Anda sudah didistribusikan langsung dengan Developer ID dan sudah memiliki pembaruan otomatis Sparkle yang terpasang. Pengaturan itu dibahas mulai dari Bagian 1 seri “Mendistribusikan Aplikasi macOS Sendiri”. Jika Anda belum membacanya, saya sarankan untuk membacanya terlebih dahulu.
Mengapa MAS Membutuhkan “Target Lain”
Aplikasi yang didistribusikan langsung menyertakan pembaruan otomatis Sparkle — fitur yang memungkinkan aplikasi memeriksa feed pembaruan sendiri, mengunduh versi baru, dan mengganti dirinya sendiri.
Tetapi aturan review Mac App Store melarang perilaku ini. Aplikasi di App Store tidak boleh mengunduh kode dari luar untuk memperbarui dirinya sendiri; pembaruan harus terjadi hanya melalui App Store. Dengan kata lain, build yang ditujukan untuk MAS tidak boleh mengandung Sparkle.
Build distribusi langsung, bagaimanapun, harus memiliki Sparkle. Satu artefak build tidak dapat memenuhi kedua persyaratan sekaligus. Jadi solusinya adalah ini:
Satu codebase, dua build target.
| Saluran | Build target | Sparkle | Didistribusikan melalui |
|---|---|---|---|
| Developer ID | FocusTimer | Disertakan | Distribusi langsung (.dmg) |
| Mac App Store | FocusTimer MAS | Dikecualikan | App Store |
Anda berbagi satu codebase, tetapi membaginya menjadi dua build target, menautkan Sparkle hanya di salah satunya. Seri ini membahas konfigurasi satu kali untuk membuat target kedua (FocusTimer MAS).
Yang Akan Dibangun dalam Seri Ini
Selama tiga bagian, Anda akan menyiapkan hal-hal berikut.
- (Bagian 1, artikel ini) Mendaftarkan Bundle ID khusus MAS + menduplikasi build target Xcode
- (Bagian 2) File konfigurasi (entitlement dan Info.plist) dan percabangan kode yang memisahkan dua saluran
- (Bagian 3)
ExportOptions-MAS.plistuntuk upload + pendaftaran App Store Connect + verifikasi build
Di akhir seri, Anda seharusnya memiliki:
- Bundle ID khusus MAS yang terdaftar di Apple Developer Portal
- Build target
FocusTimer MASdengan dependensi Sparkle dihapus - File entitlement dan Info.plist khusus MAS
- Kode yang dibercabangkan dengan
#if canImport(Sparkle) -
ExportOptions-MAS.plistuntuk upload App Store
Aplikasi Contoh — FocusTimer
Seperti dalam seri sebelumnya, kita akan menggunakan aplikasi macOS fiktif, FocusTimer (aplikasi timer sederhana untuk mengelola sesi fokus), sebagai contoh. FocusTimer, pengenal bundle com.example.FocusTimer, Team ID ABCDE12345, dan sebagainya adalah semua nilai contoh. Dalam praktiknya, gantikan dengan informasi aplikasi dan akun Anda sendiri.
Artikel ini ditulis untuk Xcode 26.
Langkah 1 — Daftarkan Bundle ID Khusus MAS
Mengapa Bundle ID Terpisah
Jika Bundle ID saluran distribusi langsung adalah com.example.FocusTimer, saluran MAS menggunakan Bundle ID yang berbeda.
| Saluran | Bundle ID |
|---|---|
| Developer ID | com.example.FocusTimer |
| Mac App Store | com.example.FocusTimer.mas |
Anda menambahkan .mas ke Bundle ID yang sudah ada. Mengapa repot-repot memisahkannya?
- Kedua saluran dapat coexist di satu Mac — Jika Bundle ID-nya sama, macOS memperlakukan dua aplikasi sebagai aplikasi yang sama dan mereka konflik. Jika berbeda, Anda dapat menginstal build distribusi langsung dan build App Store di mesin yang sama secara bersamaan (berguna untuk pengembangan dan pengujian).
- Domain
UserDefaultsterpisah — Penyimpanan pengaturan dipartisi berdasarkan Bundle ID, sehingga pengaturan dua saluran tidak tercampur. - Menghindari konflik Launch Services — Mencegah kebingungan saat macOS memutuskan aplikasi mana yang akan dikirim permintaan seperti “buka aplikasi ini.”
Pertahankan Bundle ID saluran distribusi langsung tidak berubah. Itu adalah pengenal untuk pengguna yang sudah ada, sehingga tidak boleh diubah. Anda mendaftarkan satu ID tambahan baru untuk MAS.
Prosedur Pendaftaran
- Masuk di developer.apple.com/account (dengan akun Apple Developer Program Anda)
- Certificates, Identifiers & Profiles → Identifiers di menu kiri → tombol
+ - Pilih App IDs → Continue → pilih tipe App → Continue
- Description: Masukkan nama yang mudah dikenali (misalnya,
FocusTimer MAS) - Bundle ID:
- Pilih Explicit
- Masukkan:
com.example.FocusTimer.mas
- Capabilities: Matikan setiap fitur yang tidak digunakan aplikasi. Jika Anda tidak menggunakan iCloud, notifikasi push, pembelian dalam aplikasi, Sign in with Apple, dan sebagainya, Anda tidak perlu mengaktifkan apa pun. (App Sandbox ditangani oleh entitlement di sisi Xcode, jadi tidak perlu mengaktifkannya di sini.)
- Continue → Register
Verifikasi
Jika daftar Identifiers menampilkan entri untuk FocusTimer MAS — com.example.FocusTimer.mas, pendaftaran selesai.
Langkah 2 — Duplikasi Build Target Xcode
Sekarang Anda akan membuat build target FocusTimer MAS di proyek Xcode. Cara tercepat adalah menduplikasi target yang sudah ada.
2-1. Duplikasi Target
- Buka
FocusTimer.xcodeprojdi Xcode - Klik ikon proyek (biru) di bagian atas Project navigator (panel kiri)
- Di daftar TARGETS di area pengeditan tengah, klik kanan
FocusTimer→ Duplicate - Saat dialog muncul, pilih Duplicate Only
- Target baru dibuat sebagai
FocusTimer copy. Klik dua kali nama dan ubah menjadiFocusTimer MAS - Jika prompt “Add a new Scheme?” muncul, pilih Activate (atau tambahkan nanti di Manage Schemes)
2-2. Ubah Bundle ID Segera
Hal pertama yang harus dilakukan segera setelah menduplikasi adalah menukar Bundle ID. Jika dibiarkan begitu saja, kedua target akan memiliki ID yang sama.
Ubah TARGETS → FocusTimer MAS → General → Identity → Bundle Identifier ke nilai yang Anda daftarkan di Langkah 1.
com.example.FocusTimer.mas
2-3. Jebakan Utama — “Beban Pembersihan” yang Ditinggalkan Duplikasi
Inilah bagian yang paling sulit dalam artikel ini. Xcode’s Duplicate Target beroperasi dengan “default yang aman,” tetapi keamanan itu justru meninggalkan pekerjaan pembersihan yang memerlukan perhatian manual. Tepat setelah menduplikasi, Anda perlu memeriksa empat hal berikut.
① Buat target baru menyertakan file sumber
Demi keamanan, Duplicate secara otomatis mengecualikan semua file sumber dari target baru. Jika dibiarkan begitu saja, target FocusTimer MAS adalah cangkang kosong — mem-build-nya menghasilkan build tanpa kode apa pun di dalamnya. Anda perlu memperbaiki keanggotaan target agar target baru menyertakan file sumber yang sudah ada lagi.
② Hapus dependensi Sparkle dari target MAS
Duplicate menyalin dependensi Swift Package aslinya secara verbatim. Akibatnya, Sparkle ikut terbawa ke target FocusTimer MAS juga. Titik awal seluruh seri ini adalah “build MAS tidak boleh memiliki Sparkle,” jadi hapus Sparkle dari daftar dependensi paket target MAS dan dari fase build Frameworks.
③ Bersihkan file Info.plist sementara
Duplicate membuat file Info.plist sementara seperti FocusTimer copy-Info.plist. Karena kita akan membuat Info.plist khusus MAS secara terpisah di Bagian 2, hapus file sementara ini — baik referensi proyek maupun file aktualnya.
④ Perbarui pengaturan build target MAS
Anda perlu menyesuaikan pengaturan build seperti pengenal bundle, jalur Info.plist, dan jalur entitlement untuk MAS. Kita akan menangani semua ini sekaligus di Bagian 2, setelah membuat file konfigurasi khusus.
Item ① dan ② sebagian besar dapat ditangani dari layar keanggotaan target dan dependensi paket di UI Xcode, tetapi jika referensi duplikat yang ditinggalkan oleh proses duplikasi tidak dibersihkan dengan rapi, Anda kadang perlu melihat langsung ke file proyek (
.pbxproj). Setelah Anda merasa pembersihan selesai, cara paling andal untuk memverifikasi adalah mem-build kedua target secara terpisah dan memeriksa apakahimport Sparklerusak di build target MAS (Bagian 2 membahas percabangan kode ini).
Rangkuman Bagian 1
Jika Anda telah mengikuti sejauh ini, Anda sekarang memiliki:
- ✅ Bundle ID khusus MAS (
com.example.FocusTimer.mas) yang terdaftar di Apple Developer Portal - ✅ Build target
FocusTimer MASyang dibuat dengan duplikasi - ✅ Pemahaman tentang beban pembersihan yang ditinggalkan duplikasi (keanggotaan sumber, dependensi Sparkle, file sementara)
“Wadah” — target — telah dibuat. Tetapi target ini masih pada dasarnya hanya salinan FocusTimer; belum benar-benar menjadi “khusus MAS.” Build MAS perlu menggunakan entitlement yang berbeda dan Info.plist yang berbeda dari build distribusi langsung, dan kode juga harus dibercabangkan agar tidak rusak saat Sparkle tidak ada.
Di bagian berikutnya, kita akan membahas file konfigurasi dan percabangan kode yang memisahkan dua saluran.