Untuk menyokong keluaran macOS yang lebih lama, bina dengan SDK yang mengenali API lebih baharu, tetapkan sasaran penggunaan minimum yang disokong, dan lindungi panggilan baharu dengan semakan ketersediaan serta sandaran yang berfungsi. Panduan ini memastikan tetingkap nota asli yang kecil boleh digunakan pada macOS 12 sambil menggunakan paparan macOS 14.

Tetapan keserasian manakah yang mesti sepadan?

Bagi pembangun apl Mac, tugas sebenarnya ialah menghasilkan satu apl yang dilancarkan pada keluaran tertua yang disokong dan menggunakan ciri lebih baharu apabila tersedia. Mulakan dengan memisahkan tiga input: pengkompil memahami bahasa sumber, SDK menyediakan pengisytiharan API, dan sasaran penggunaan mengenal pasti masa jalan tertua yang disasarkan. Rujukan tetapan binaan Apple mentakrifkan SDKROOT sebagai SDK yang pengepala dan pustakanya digunakan dalam binaan. Rujukan tetapan binaan

SDK lebih baharu dan sasaran penggunaan yang lebih lama boleh digunakan bersama. Clang mendokumenkan secara jelas pembinaan menggunakan SDK terkini sambil memilih minimum macOS terdahulu dengan -mmacos-version-min=. Gabungan itu tetap memerlukan semakan ketersediaan di sekeliling API yang diperkenalkan selepas minimum tersebut. Sambungan Bahasa Clang

Pilih minimum yang benar-benar disokong oleh Xcode yang anda pilih. Jadual keserasian Apple membezakan versi macOS yang diperlukan untuk menjalankan Xcode daripada sasaran penggunaan yang boleh dibinanya. Jika minimum yang anda inginkan di luar julat yang disokong oleh toolchain itu, pilih toolchain lain yang sesuai dan disokong atau semak semula minimum apl sebelum melaksanakan sandaran. SDK dan keperluan sistem

Bagi contoh sintetik ini, ketetapannya ialah macOS 12 atau lebih baharu, SDK yang mengandungi API macOS 14, dan tetingkap nota dengan dua keadaan: koleksi kosong dan satu nota contoh. Persembahan keadaan kosong yang lebih baharu adalah pilihan; paparan nota tetap tersedia pada sistem asas.

Tetapkan minimum dalam kedua-dua konfigurasi binaan

Dalam Build Settings sasaran apl, tetapkan MACOSX_DEPLOYMENT_TARGET kepada 12.0 untuk kedua-dua Debug dan Release. Jika anda mengurus tetapan dalam fail konfigurasi, yang berikut ialah cebisan konfigurasi lengkap, bukannya program:

MACOSX_DEPLOYMENT_TARGET = 12.0

Berikan fail konfigurasi itu kepada konfigurasi yang dimaksudkan dalam tab Info projek. Selepas itu, semak nilai akhir sasaran: Apple mendokumenkan bahawa tetapan sasaran boleh mengatasi nilai daripada fail konfigurasi yang diberikan. Menambah fail itu sahaja ke projek tidak menjadikan tetapan di dalamnya berkuat kuasa. Menambah fail konfigurasi binaan pada projek anda

Bagaimanakah anda menambah API lebih baharu tanpa menaikkan minimum apl?

Semakan if #available dalam Swift memeriksa ketersediaan masa jalan dan memberitahu pengkompil API yang dibenarkan dalam cabang tersebut. Letakkan sandaran dalam keputusan yang sama supaya sistem lebih lama mempunyai pelaksanaan yang lengkap. * yang diwajibkan meliputi platform yang tidak dinamakan secara jelas; ia tidak menjadikan API macOS yang dinamakan tersedia pada keluaran terdahulu. Aliran Kawalan — Menyemak Ketersediaan API

ContentUnavailableView Apple tersedia mulai macOS 14 dan menyokong persembahan kandungan kosong. Di sini, VStack kecil menyediakan persembahan yang setara pada macOS 12 dan 13. Kedua-dua cabang menyampaikan tindakan seterusnya yang sama. ContentUnavailableView

Apl SwiftUI sintetik yang lengkap

Cipta projek apl macOS bernama CompatibilityNotes, pilih Swift dan SwiftUI, lalu tetapkan sasaran penggunaannya kepada 12.0. Gunakan SDK yang mengandungi API macOS 14. Gantikan pengisytiharan apl dan paparan kandungan yang dijana dengan satu fail berikut, dan pastikan sasaran itu hanya mengandungi satu pengisytiharan @main. Tiada aset, pakej atau fail input diperlukan.

import SwiftUI

@main
struct CompatibilityNotesApp: App {
    var body: some Scene {
        WindowGroup {
            NotesView()
        }
    }
}

struct NotesView: View {
    @State private var notes: [String] = []

    var body: some View {
        VStack(spacing: 16) {
            if notes.isEmpty {
                emptyState
            } else {
                List(notes, id: \.self) { note in
                    Text(note)
                }
            }

            Button(notes.isEmpty ? "Add sample note" : "Reset sample") {
                if notes.isEmpty {
                    notes = ["Sample note: arrange the blue shapes."]
                } else {
                    notes = []
                }
            }
        }
        .padding()
        .frame(minWidth: 360, minHeight: 240)
    }

    @ViewBuilder
    private var emptyState: some View {
        if #available(macOS 14.0, *) {
            ModernEmptyState()
        } else {
            VStack(spacing: 8) {
                Text("No notes")
                    .font(.headline)
                Text("Add a sample note to begin.")
            }
        }
    }
}

@available(macOS 14.0, *)
private struct ModernEmptyState: View {
    var body: some View {
        ContentUnavailableView {
            Label("No notes", systemImage: "note.text")
        } description: {
            Text("Add a sample note to begin.")
        }
    }
}

Tingkah laku yang dimaksudkan adalah mudah: macOS 12 dan 13 memaparkan teks sandaran; macOS 14 dan keluaran lebih baharu memaparkan ContentUnavailableView. Memilih Add sample note memaparkan nota sintetik. Memilih Reset sample memulihkan keadaan kosong. Demonstrasi ini menyimpan datanya dalam memori dan tidak menyimpan nota antara pelancaran.

Anotasi @available mengehadkan penggunaan pembantu itu kepada macOS 14 dan keluaran lebih baharu. Cabang #available pemanggil memenuhi sekatan tersebut. Anotasi menerangkan ketersediaan pengisytiharan; ia tidak menyediakan pelaksanaan untuk sistem lebih lama. Atribut — available

Contoh ini disemak berdasarkan dokumentasi yang diperoleh tetapi tidak dikompil atau dijalankan: persekitaran pelaksanaan yang tersedia ialah Linux dan tidak mempunyai Swift atau Clang. Pemeriksaan binaan dan masa jalan pada macOS masih diperlukan.

Apakah yang diselesaikan oleh semakan ketersediaan pada masa pemautan?

Cabang masa jalan hanya berguna jika boleh laksana itu dapat dimuatkan. Clang mendokumenkan bahawa pengisytiharan beranotasi ketersediaan yang diperkenalkan selepas sasaran penggunaan biasanya boleh dipaut secara lemah. Rujukan lemah membenarkan pengisytiharan itu tiada pada masa jalan; aplikasi masih perlu mengelak daripada menggunakannya jika tiada. Oleh itu, sasaran penggunaan dan pengisytiharan yang dilihat semasa kompilasi tetap penting bersama-sama cabang tersebut. Atribut dalam Clang — availability

Untuk contoh ini, pautkan SwiftUI seperti biasa: rangka kerja itu sudah tersedia pada macOS 12. Sempadan keserasian mengelilingi paparan yang lebih baharu. Jika rangka kerja yang sepenuhnya baharu tiada pada sistem asas anda, nilai kebergantungan rangka kerja itu sendiri; melindungi satu panggilan tidak menyelesaikan semua keperluan pemuatan. Panduan pemautan lemah Apple menerangkan perbezaan antara membenarkan simbol tiada dengan menggunakan simbol itu. Rangka Kerja dan Pemautan Lemah

Gunakan sintaks ketersediaan yang sesuai dengan bahasa sumber:

Bahasa sumber Syarat ketersediaan masa jalan
Swift if #available(macOS 14.0, *)
Objective-C atau Objective-C++ if (@available(macOS 14.0, *))
C atau C++ dengan sokongan platform Apple oleh Clang if (__builtin_available(macOS 14.0, *))

Clang mendokumenkan ejaan Objective-C dan builtin C/C++, bersama-sama -Wunguarded-availability. Aktifkan diagnostik ketersediaan untuk kod keluarga C dan siasat amaran sebelum menganggap sasaran penggunaan yang lebih lama boleh digunakan. Sambungan Bahasa Clang

Bagaimana jika SDK binaan tidak mengandungi API tersebut?

Semakan masa jalan tidak dapat menyediakan pengisytiharan yang tiada daripada SDK. Jika pengkompil tidak dapat mengenal pasti ContentUnavailableView, bina dengan SDK yang mengandunginya. Jika projek itu juga mesti dibina dengan SDK lebih lama, sediakan aturan sumber bersyarat yang disengajakan untuk mengecualikan rujukan yang tidak disokong daripada binaan tersebut.

#if compiler(...) dalam Swift menguji versi pengkompil, manakala #if canImport(...) menguji sama ada modul boleh diimport. Kedua-dua syarat ini tidak menentukan bahawa ahli tertentu dalam modul sedia ada tersedia pada Mac yang sedang digunakan. Gunakan syarat kompilasi ini untuk tujuan yang didokumenkan, kemudian gunakan semakan ketersediaan masa jalan apabila perlu. Pernyataan — Blok Kompilasi Bersyarat

Bilakah had ABI Swift dan pustaka C++ mengubah jawapannya?

Kestabilan ABI Swift tidak menjadikan setiap ciri pustaka standard atau masa jalan yang lebih baharu tersedia pada sistem lama. Penjelasan Swift membezakan mod bahasa sumber daripada sokongan masa jalan: perubahan mod bahasa ialah pilihan masa kompilasi, manakala ciri yang memerlukan fungsi masa jalan baharu mungkin mempunyai keperluan OS. Ikut ketersediaan ciri khusus yang anda gunakan. Mengembangkan Swift pada Platform Apple selepas Kestabilan ABI

C++ juga memisahkan sokongan pengkompil daripada sokongan pustaka. Apple menyediakan Apple Clang melalui Xcode dan masa jalan libc++ melalui SDK dan sistem pengendaliannya. Jadual cirinya mengenal pasti keperluan yang boleh bergantung pada pustaka kongsi yang disediakan OS. Memilih -std=c++17 atau -std=c++20 tidak memasang fungsi masa jalan itu pada Mac pengguna. Sokongan bahasa C++

Penukaran angka ialah contoh yang berguna: Apple menyenaraikan macOS 10.15 sebagai minimum bagi std::to_chars dan std::from_chars berjenis integer, tetapi macOS 13.3 bagi lebihan beban titik terapungnya. Oleh itu, apl macOS 12 memerlukan pelaksanaan penukaran yang serasi jika apl itu bergantung pada lebihan beban titik terapung tersebut. Semak lebihan beban yang tepat, bukan sekadar pengepala atau versi piawaian C++. Sokongan bahasa C++

Jangan anggap bahawa membalut setiap panggilan pustaka C++ dalam __builtin_available sudah mencukupi. Atribut ketersediaan Clang termasuk bentuk strict yang menolak penggunaan apabila menyasarkan platform lebih lama, dan libc++ menggunakan penanda ketersediaan untuk mendiagnosis ketiadaan sokongan masa jalan semasa kompilasi. Jika pengepala yang dipilih menolak operasi itu, gunakan pelaksanaan yang serasi dengan sistem asas atau naikkan minimum. Atribut dalam Clang — availability, Dokumentasi Vendor — Penanda Ketersediaan

Kekalkan konfigurasi ABI pustaka yang sama merentas kebergantungan. LLVM mendokumenkan jaminan ABI tertentu serta hadnya, termasuk hakikat bahawa kod yang dikompil dengan pengepala libc++ lebih baharu mungkin tidak berfungsi dengan pustaka yang lebih lama. Bendera konfigurasi yang mengubah ABI ialah kawalan vendor. Mengubahnya dalam kod aplikasi bukan pengganti masa jalan yang serasi. Jaminan ABI libc++

Bagaimanakah anda mendiagnosis dan mengesahkan binaan yang siap?

Gunakan peringkat kegagalan untuk menentukan penyiasatan seterusnya. Panduan keputusan ini mengikuti sempadan pengkompil, ketersediaan dan masa jalan di atas; ini ialah urutan diagnostik, bukannya dakwaan bahawa sampel telah lulus ujian.

Gejala Perkara pertama untuk disiasat Langkah seterusnya yang praktikal
Nama API baharu tidak dikenali Pengisytiharan SDK Pilih SDK yang mengandungi API tersebut.
API lebih baharu daripada sasaran penggunaan Penggunaan tanpa perlindungan Tambah sempadan ketersediaan yang disokong dan sandaran.
Operasi pustaka C++ masih ditolak Lebihan beban tepat dan keperluan pustaka Gunakan pelaksanaan yang serasi atau semak semula minimum.
Apl gagal sebelum tetingkapnya muncul Keperluan pemuatan dan kebergantungan Periksa pustaka atau simbol yang dilaporkan hilang.
Hanya ciri lebih baharu yang gagal Kerja yang dilakukan di luar cabang terlindung Periksa panggilan penciptaan, pemulaan dan pembantu.
Binaan hanya berfungsi pada satu keluarga pemproses Seni bina boleh laksana dan kebergantungan Bina dan uji hirisan seni bina yang diperlukan.

Sokongan seni bina ialah keperluan tambahan. Panduan binari universal Apple meliputi arm64 dan x86_64, termasuk pustaka dan rangka kerja yang dikompil. Sahkan kebergantungan serta boleh laksana apl; binaan yang berjaya untuk Mac pembangunan anda hanya membuktikan keserasian bagi binaan itu. Membina binari macOS universal

Untuk sampel ini, bina konfigurasi keluaran dan uji apl yang terhasil pada macOS 12, macOS 13 dan macOS 14 atau lebih baharu, pada perkakasan yang disokong. Pada setiap sistem, lancarkan apl dengan koleksi kosong, tambah nota contoh dan tetapkan semula. Keluaran lebih lama sepatutnya mengekalkan interaksi lengkap melalui sandaran. Uji setiap seni bina yang ingin anda edarkan.

Kekalkan sempadan sokongan dengan jelas apabila apl berkembang: sasaran penggunaan yang disokong, pengisytiharan daripada SDK yang sesuai, fungsi lebih baharu yang dilindungi, dan pelaksanaan asas yang berguna. Setiap API atau kebergantungan tambahan perlu memenuhi ketetapan yang sama sebelum dimasukkan dalam binaan.

Sumber