Core Bluetooth: arsitektur dan pengembangan BLE di iOS

Penulis: IT Sectr Diterbitkan: 2026-07-16 Waktu membaca: 10 mnt

Core Bluetooth adalah framework Apple untuk interaksi dengan Bluetooth Low Energy di iOS, iPadOS, dan macOS. Framework ini menyediakan serangkaian API lengkap untuk bekerja dalam kedua peran BLE: perangkat pusat (CBCentralManager) untuk memindai dan terhubung ke periferal, dan perangkat periferal (CBPeripheralManager) untuk emulasi server BLE. Core Bluetooth mengabstraksi tumpukan protokol BLE dari radio fisik hingga profil GATT aplikasi. Menurut Apple Developer, 2026, Core Bluetooth adalah satu-satunya API resmi Apple untuk pengembangan BLE, mendukung BLE 4.0–5.4 dengan extended advertising, 2M PHY, dan LE Audio.

Poin Utama

  • Core Bluetooth — framework sistem Apple untuk pengembangan BLE di iOS, iPadOS, dan macOS
  • CBCentralManager — kelas untuk memindai dan terhubung ke periferal BLE dari sisi perangkat pusat
  • CBPeripheralManager — kelas untuk membuat server BLE yang mempublikasikan layanan dan karakteristik
  • Profil GATT — model hierarkis layanan, karakteristik, dan deskriptor untuk pertukaran data
  • Mode latar belakang — Core Bluetooth mendukung komunikasi BLE di latar belakang melalui delegat sistem dan state restoration

Apa itu Core Bluetooth: arsitektur dan komponen

Core Bluetooth membagi tumpukan BLE menjadi dua peran logis yang ditentukan oleh spesifikasi Bluetooth SIG. Peran perangkat pusat (Central) diwakili oleh kelas CBCentralManager — memulai pemindaian, membuat koneksi, dan mengelola daftar CBPeripheral yang terhubung. Peran perangkat periferal (Peripheral) diwakili oleh CBPeripheralManager — mempublikasikan layanan dan karakteristik, merespons permintaan dari pusat, dan mengirim notifikasi. Satu sesi iOS dapat bekerja secara bersamaan dalam kedua peran pada radio BLE yang berbeda, tetapi aplikasi tipikal menggunakan satu peran.

Arsitektur Core Bluetooth mencakup lima abstraksi kunci. CBCentralManager mengelola status adaptor Bluetooth perangkat: poweredOn (siap bekerja), poweredOff (Bluetooth dinonaktifkan), unauthorized (tanpa izin), unsupported (BLE tidak tersedia). CBPeripheral mewakili perangkat BLE jarak jauh dengan UUID, nama, RSSI, dan hierarki GATT-nya. CBService — grup logis karakteristik. CBCharacteristic — titik data untuk membaca/menulis/notifikasi. CBPeripheralManager membuat server GATT lokal untuk emulasi periferal.

KelasPeranMetode utama
CBCentralManagerPerangkat pusatscanForPeripherals, connect, cancelPeripheralConnection, retrievePeripherals
CBPeripheralPeriferal jarak jauhdiscoverServices, discoverCharacteristics, readValue, writeValue, setNotifyValue
CBPeripheralManagerPeriferal lokaladdService, removeService, startAdvertising, respondToRequest, updateValue
CBCentralPusat jarak jauhmaximumUpdateValueLength, identifier, ancsAuthorized

Status CBCentralManager mengelola semua operasi BLE. Saat aplikasi dimulai, centralManagerDidUpdateState dipanggil dengan status Bluetooth saat ini. Jika status bukan .poweredOn, panggilan BLE apa pun akan diabaikan oleh sistem. Pengembang harus memeriksa state sebelum setiap pemindaian dan koneksi. Transisi dari .poweredOff ke .poweredOn terjadi ketika Bluetooth diaktifkan di Pengaturan iOS — delegat menerima panggilan ulang dan aplikasi dapat melanjutkan pemindaian.

CBCentralManager: memindai dan menghubungkan perangkat BLE

CBCentralManager — titik masuk untuk semua operasi BLE dari sisi perangkat pusat. Inisialisasi menerima delegat (CBCentralManagerDelegate) dan antrean DispatchQueue — rekomendasi Apple menggunakan main queue untuk kesederhanaan atau serial queue untuk kinerja. Setelah inisialisasi, framework secara otomatis memeriksa status Bluetooth dan memanggil centralManagerDidUpdateState: — delegat wajib pertama untuk diproses.

Pemindaian dimulai dengan metode scanForPeripheralsWithServices:options:. Parameter pertama adalah array CBUUID layanan untuk pemfilteran: jika UUID layanan yang diminati diketahui, meneruskannya akan mengurangi konsumsi daya dan waktu pencarian. Jika nil, semua perangkat BLE dalam jangkauan terdeteksi. Opsi termasuk .allowDuplicatesKey (deteksi berulang perangkat yang sama) dan .solicitedServiceUUIDsKey (untuk layanan yang dipublikasikan di pusat).

swift
import CoreBluetooth

class BLECentral: NSObject {

    private var centralManager: CBCentralManager!
    private var discoveredPeripherals: [CBPeripheral] = []

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: .main)
    }

    // Mulai pemindaian BLE
    func startScan() {
        guard centralManager.state == .poweredOn else {
            print("Bluetooth tidak tersedia")
            return
        }
        // Pindai semua perangkat (nil = tanpa filter)
        centralManager.scanForPeripherals(withServices: nil,
                                            options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
    }

    // Hentikan pemindaian
    func stopScan() {
        centralManager.stopScan()
    }

    // Hubungkan ke perangkat yang dipilih
    func connect(to peripheral: CBPeripheral) {
        centralManager.connect(peripheral, options: nil)
    }
}

// MARK: - CBCentralManagerDelegate
extension BLECentral: CBCentralManagerDelegate {

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            startScan()
        }
    }

    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any],
                        rssi: NSNumber) {
        if !discoveredPeripherals.contains(where: { $0.identifier == peripheral.identifier }) {
            discoveredPeripherals.append(peripheral)
            print("Found devices: \(peripheral.name ?? "Unknown"), RSSI: \(rssi)")
        }
    }

    func centralManager(_ central: CBCentralManager,
                        didConnect peripheral: CBPeripheral) {
        print("Connected: \(peripheral.identifier)")
        peripheral.delegate = self
        peripheral.discoverServices(nil)
    }

    func centralManager(_ central: CBCentralManager,
                        didDisconnectPeripheral peripheral: CBPeripheral,
                        error: Error?) {
        print("Disconnected: \(peripheral.identifier)")
    }
}

Kelas BLECentral menunjukkan siklus lengkap pemindaian dan koneksi perangkat BLE. centralManagerDidUpdateState memulai pemindaian saat Bluetooth aktif. didDiscoverPeripheral mengumpulkan perangkat yang ditemukan dalam array discoveredPeripherals dengan deduplikasi berdasarkan identifier. Setelah terhubung (didConnect), discovery layanan segera dimulai — ini adalah langkah wajib sebelum operasi GATT apa pun.

CBPeripheralManager: membuat server BLE di iOS

CBPeripheralManager — kelas untuk emulasi perangkat periferal BLE di iOS. Aplikasi dalam peran periferal dapat mempublikasikan layanan dan karakteristiknya sendiri, menerima permintaan baca/tulis masuk dari perangkat pusat, dan mengirim notifikasi. CBPeripheralManager digunakan untuk aksesori BLE yang diemulasi oleh iPhone: remote, keyboard, tracker, gateway IoT.

Siklus hidup CBPeripheralManager dimulai dengan inisialisasi dan delegat CBPeripheralManagerDelegate. Setelah konfirmasi poweredOn melalui peripheralManagerDidUpdateState:, layanan dipublikasikan (addService:) dan advertising dimulai (startAdvertising:). Data advertising CBAdvertisementData mencakup nama lokal (CBAdvertisementDataLocalNameKey), UUID layanan (CBAdvertisementDataServiceUUIDsKey), dan tingkat daya (CBAdvertisementDataTxPowerLevelKey). Ukuran maksimum paket advertising adalah 31 byte untuk BLE 4.0, 251 byte untuk extended advertising BLE 5.0+.

swift
// Periferal BLE di iOS melalui CBPeripheralManager
class BLEPeripheral: NSObject {

    private var peripheralManager: CBPeripheralManager!

    let serviceUUID = CBUUID(string: "1234")
    let characteristicUUID = CBUUID(string: "5678")

    override init() {
        super.init()
        peripheralManager = CBPeripheralManager(delegate: self, queue: .main)
    }

    // Publikasikan layanan dengan karakteristik
    func setupService() {
        let characteristic = CBMutableCharacteristic(
            type: characteristicUUID,
            properties: [.read, .write, .notify],
            value: nil,
            permissions: [.readable, .writeable]
        )
        let service = CBMutableService(type: serviceUUID, primary: true)
        service.characteristics = [characteristic]
        peripheralManager.add(service)
    }

    // Mulai advertising
    func startAdvertising() {
        let advertisementData: [String: Any] = [
            CBAdvertisementDataLocalNameKey: "My BLE Device",
            CBAdvertisementDataServiceUUIDsKey: [serviceUUID]
        ]
        peripheralManager.startAdvertising(advertisementData)
    }
}

// MARK: - CBPeripheralManagerDelegate
extension BLEPeripheral: CBPeripheralManagerDelegate {

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        if peripheral.state == .poweredOn {
            setupService()
        }
    }

    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didAdd service: CBService,
                        error: Error?) {
        if error == nil {
            startAdvertising()
        }
    }

    // Tangani permintaan baca
    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didReceiveRead request: CBATTRequest) {
        let data = "CurrentValue".data(using: .utf8)!
        request.value = data
        peripheralManager.respond(to: request, withResult: .success)
    }

    // Tangani permintaan tulis
    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didReceiveWrite requests: [CBATTRequest]) {
        for request in requests {
            if let value = request.value {
                print("Write: \(value)")
            }
        }
        peripheralManager.respond(to: requests.first!, withResult: .success)
    }
}

Kelas BLEPeripheral membuat server BLE dengan satu karakteristik yang mendukung pembacaan, penulisan, dan notifikasi. Setelah inisialisasi, peripheralManagerDidUpdateState mempublikasikan layanan melalui addService:, kemudian memulai advertising melalui startAdvertising:. Handler didReceiveRead dan didReceiveWrite merespons permintaan GATT masuk dari perangkat pusat. Untuk mengirim notifikasi, digunakan metode updateValue:forCharacteristic:onSubscribedCentrals:.

Operasi GATT: membaca, menulis, dan notifikasi

Operasi GATT (Generic Attribute Profile) — dasar pertukaran data di Core Bluetooth. Setelah discovery layanan dan karakteristik, perangkat pusat dapat melakukan tiga jenis operasi: membaca nilai karakteristik, menulis nilai, dan berlangganan notifikasi/indikasi. Setiap operasi bersifat asinkron dan mengembalikan hasil melalui delegat CBPeripheralDelegate yang sesuai.

Membaca dilakukan dengan memanggil readValueForCharacteristic:. Nilai tiba di peripheral:didUpdateValueForCharacteristic:error:. Penting: pembacaan mengembalikan nilai saat ini dari perangkat, bukan yang di-cache. Jika perangkat tidak mendukung pembacaan (properti .read), panggilan akan mengembalikan kesalahan. Untuk nilai besar (lebih besar dari MTU), BLE secara otomatis memecah dan merakit data di tingkat GATT.

Menulis dilakukan dengan writeValue:forCharacteristic:type:. BLE mendukung dua model penulisan: withResponse (andal, dengan konfirmasi) dan withoutResponse (cepat, tanpa konfirmasi). Properti CBCharacteristic.properties menentukan jenis penulisan yang tersedia. Ukuran maksimum satu paket tulis dibatasi oleh MTU: 23 byte untuk BLE 4.0 (20 byte data berguna + 3 byte header), hingga 247 byte untuk BLE 5.0 dengan extended MTU (MTU 251).

Notifikasi diaktifkan dengan memanggil setNotifyValue:true forCharacteristic:. Setelah berlangganan, periferal secara otomatis mengirim pembaruan melalui peripheral:didUpdateValueForCharacteristic: setiap kali nilai karakteristik berubah. Untuk menonaktifkan notifikasi, panggil setNotifyValue:false forCharacteristic:. Core Bluetooth secara otomatis mengelola deskriptor CCCD di periferal.

OperasiMetodeDelegatJenis transmisi
MembacareadValueForCharacteristic:didUpdateValueForCharacteristicPolling (permintaan-respons)
Menulis withResponsewriteValue:forCharacteristic:type:withResponsedidWriteValueForCharacteristicDengan konfirmasi
Menulis withoutResponsewriteValue:forCharacteristic:type:withoutResponseTidak ada delegatTanpa konfirmasi
NotifikasisetNotifyValue:true forCharacteristic:didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristicPush dari periferal

Mode latar belakang Core Bluetooth dan State Restoration

Mode latar belakang Core Bluetooth memungkinkan aplikasi BLE untuk terus memindai, mempertahankan koneksi, dan menerima notifikasi saat berada di latar belakang. Untuk aktivasi diperlukan: aktifkan capability “Uses Bluetooth LE accessories” di Xcode (Info.plist → Required background modes → App communicates using Core Bluetooth) dan tambahkan kunci „bluetooth-central” ke UIBackgroundModes. Untuk peran periferal — „bluetooth-peripheral”.

State Restoration — mekanisme Core Bluetooth untuk memulihkan status koneksi BLE setelah aplikasi dimulai ulang oleh sistem iOS. Saat mode latar belakang diaktifkan dan restoreIdentifier ditentukan dalam inisialisasi CBCentralManager atau CBPeripheralManager, iOS menyimpan status tumpukan BLE saat aplikasi berakhir dan memulihkannya saat startup berikutnya. Delegat centralManager:willRestoreState: menerima kamus dengan CBPeripheral yang disimpan dan koneksi yang tertunda.

swift
// Konfigurasi Core Bluetooth dengan State Restoration
class BLECentralWithRestoration: NSObject {

    let restoreIdentifier = "com.app.blecentral"
    private var centralManager: CBCentralManager!

    override init() {
        super.init()
        let options: [String: Any] = [
            CBCentralManagerOptionRestoreIdentifierKey: restoreIdentifier,
            CBCentralManagerOptionShowPowerAlertKey: true
        ]
        centralManager = CBCentralManager(delegate: self,
                                          queue: nil,
                                          options: options)
    }
}

extension BLECentralWithRestoration: CBCentralManagerDelegate {

    // Pulihkan status setelah restart
    func centralManager(_ central: CBCentralManager,
                        willRestoreState dict: [String : Any]) {
        if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]
            as? [CBPeripheral] {
            for peripheral in peripherals {
                peripheral.delegate = self
                // Pulihkan discovery GATT
                peripheral.discoverServices(nil)
            }
        }
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            print("Bluetooth siap setelah pemulihan")
        }
    }
}

Dalam konfigurasi BLECentralWithRestoration, kunci CBCentralManagerOptionRestoreIdentifierKey mengaktifkan penyimpanan status. Jika aplikasi diakhiri oleh iOS (misalnya karena kehabisan memori), pada startup berikutnya centralManager:willRestoreState: menerima daftar CBPeripheral yang sebelumnya terhubung. Aplikasi memulihkan delegat dan melakukan discovery ulang layanan — pengguna tidak melihat pemutusan koneksi. Tanpa State Restoration, semua sesi BLE hilang saat aplikasi berakhir.

Contoh aplikasi BLE di Swift: pusat dan periferal

Contoh lengkap aplikasi BLE di Swift menggabungkan perangkat pusat dan periferal dalam satu proyek. Aplikasi dapat bekerja dalam dua mode: mendeteksi dan terhubung ke perangkat BLE (Central) atau meniru aksesori BLE (Peripheral). Di bawah ini disajikan arsitektur dengan manajer BLE bersama yang memilih peran saat startup.

swift
// Manajer BLE universal untuk pusat dan periferal
class BLEManager {

    enum Role {
        case central
        case peripheral
    }

    private let role: Role
    private var centralManager: CBCentralManager?
    private var peripheralManager: CBPeripheralManager?
    let advertisedServiceUUID = CBUUID(string: "A001")

    init(role: Role) {
        self.role = role
        switch role {
        case .central:
            centralManager = CBCentralManager(delegate: nil, queue: .main)
        case .peripheral:
            peripheralManager = CBPeripheralManager(delegate: nil, queue: .main)
        }
    }

    // Perangkat pusat: pemindaian
    func scanForDevices() {
        centralManager?.scanForPeripherals(withServices: nil, options: nil)
    }

    // Perangkat periferal: advertising
    func advertiseService() {
        let data: [String: Any] = [
            CBAdvertisementDataServiceUUIDsKey: [advertisedServiceUUID]
        ]
        peripheralManager?.startAdvertising(data)
    }
}

// Penggunaan saat startup
let isCentral = UserDefaults.standard.bool(forKey: "isCentral")
let manager = BLEManager(role: isCentral ? .central : .peripheral)

if isCentral {
    manager.scanForDevices()
} else {
    manager.advertiseService()
}

Manajer BLEManager memilih peran saat inisialisasi dan membuat Manager yang sesuai (CBCentralManager atau CBPeripheralManager). Bendera peran dapat disimpan di UserDefaults atau diteruskan melalui server konfigurasi. Pendekatan ini memungkinkan aplikasi BLE beradaptasi dengan skenario penggunaan: di titik penjualan, iPhone bekerja sebagai pusat untuk memindai terminal pembayaran, di gateway IoT — sebagai periferal untuk mengumpulkan data dari sensor.

Pertanyaan yang Sering Diajukan

Apa itu Core Bluetooth?

Core Bluetooth — framework Apple untuk pengembangan BLE di iOS, iPadOS, dan macOS. Menyediakan API untuk pengoperasian perangkat pusat (CBCentralManager) dan periferal (CBPeripheralManager). Mendukung BLE 4.0–5.4, extended advertising, 2M PHY, dan LE Audio. Core Bluetooth adalah satu-satunya API resmi Apple untuk komunikasi BLE, wajib untuk semua aplikasi iOS yang bekerja dengan Bluetooth Low Energy.

Apa perbedaan antara CBCentralManager dan CBPeripheralManager?

CBCentralManager — kelas untuk bekerja dalam peran perangkat pusat: memindai periferal BLE, membuat koneksi, membaca dan menulis karakteristik. CBPeripheralManager — kelas untuk bekerja dalam peran periferal: mempublikasikan layanan, merespons permintaan baca/tulis, dan mengirim notifikasi. Satu iPhone dapat bekerja dalam dua peran secara bersamaan melalui instance manajer yang berbeda.

Bagaimana cara mengonfigurasi Core Bluetooth untuk kerja latar belakang?

Untuk kerja BLE di latar belakang, aktifkan capability „Uses Bluetooth LE accessories” di Xcode dan tambahkan kunci „bluetooth-central” ke UIBackgroundModes. Untuk peran periferal — „bluetooth-peripheral”. Tentukan restoreIdentifier saat inisialisasi manajer untuk State Restoration. Tanpa pengaturan ini, aplikasi di latar belakang tidak menerima peristiwa BLE dan kehilangan koneksi.

Mengapa Core Bluetooth tidak menemukan perangkat?

Penyebab utama: CBCentralManager.state != .poweredOn (Bluetooth dinonaktifkan atau tidak diotorisasi), delegat tidak diatur, perangkat di luar jangkauan atau tidak mengirim paket advertising. Periksa izin NSBluetoothAlwaysUsageDescription di Info.plist, status Bluetooth di centralManagerDidUpdateState, dan pastikan scanForPeripherals hanya dipanggil saat .poweredOn.

Bisakah beberapa CBPeripheral terhubung secara bersamaan?

Ya, Core Bluetooth mendukung koneksi simultan ke beberapa perangkat BLE. Setiap CBPeripheral dikelola secara independen melalui delegatnya sendiri. iOS membatasi jumlah koneksi BLE simultan di tingkat sistem (biasanya 5–7 untuk iPhone). Untuk skenario 1:N (misalnya, pusat kebugaran dengan 10 pelacak), diperlukan antrian dan layanan siklik periferal.

Ringkasan

  • Core Bluetooth — framework sistem Apple untuk pengembangan BLE dengan kelas CBCentralManager dan CBPeripheralManager
  • CBCentralManager mengelola pemindaian, koneksi, dan operasi GATT dengan perangkat BLE jarak jauh
  • CBPeripheralManager meniru periferal BLE dengan publikasi layanan dan pemrosesan permintaan masuk
  • Profil GATT mencakup layanan, karakteristik, dan deskriptor dengan operasi baca, tulis, dan notifikasi
  • Mode latar belakang memerlukan UIBackgroundModes dan restoreIdentifier untuk State Restoration
  • MTU BLE membatasi ukuran paket: 23 byte untuk BLE 4.0, hingga 251 byte untuk BLE 5.0+ dengan extended MTU
  • Swift async/await melalui CheckedContinuation menyederhanakan kode BLE asinkron dengan delegat

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga