CBPeripheral: คืออะไร เมธอด และการจัดการอุปกรณ์ต่อพ่วง BLE บน iOS

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-16 เวลาอ่าน: 10 นาที

CBPeripheral เป็นคลาสของเฟรมเวิร์ก Core Bluetooth ที่แทนอุปกรณ์ BLE ระยะไกลบน iOS วัตถุ CBPeripheral แต่ละตัวห่อหุ้ม UUID, ชื่อ, RSSI และลำดับชั้นบริการ GATT ของอุปกรณ์ BLE ที่เชื่อมต่อ นักพัฒนาโต้ตอบกับอุปกรณ์ต่อพ่วงผ่าน CBPeripheral เท่านั้น: การค้นหาบริการ (discoverServices:), การอ่านคุณลักษณะ (readValueForCharacteristic:), การเขียนข้อมูล (writeValue:forCharacteristic:type:) และการสมัครรับการแจ้งเตือน (setNotifyValue:forCharacteristic:) ตาม Apple Developer, 2026, CBPeripheral เป็นวัตถุศูนย์กลางสำหรับการดำเนินการกับอุปกรณ์ต่อพ่วง BLE ทั้งหมด ซึ่งส่งคืนโดย CBCentralManager เมื่อค้นพบหรือเชื่อมต่ออุปกรณ์

ประเด็นสำคัญ

  • CBPeripheral เป็นคลาส Core Bluetooth สำหรับทำงานกับอุปกรณ์ BLE ระยะไกลบน iOS
  • ลำดับชั้น GATT — Peripheral ประกอบด้วยบริการ (CBService), บริการประกอบด้วยคุณลักษณะ (CBCharacteristic), คุณลักษณะประกอบด้วยตัวอธิบาย (CBDescriptor)
  • การค้นพบ — discoverServices: และ discoverCharacteristics:forService: เพื่อรับโครงสร้าง GATT ของอุปกรณ์
  • การอ่านและการเขียน — readValueForCharacteristic: และ writeValue:forCharacteristic:type: พร้อมการตอบกลับ (withResponse) หรือไม่มีการตอบกลับ (withoutResponse)
  • การแจ้งเตือน — setNotifyValue:forCharacteristic: เปิดใช้งานการสมัครรับการเปลี่ยนแปลงคุณลักษณะของอุปกรณ์ BLE

CBPeripheral คืออะไร: แก่นแท้และวัตถุประสงค์

CBPeripheral เป็นวัตถุที่แทนอุปกรณ์ BLE ระยะไกลในแอปพลิเคชัน iOS ต่างจาก CBCentralManager ที่จัดการอะแดปเตอร์ Bluetooth ในเครื่องของ iPhone, CBPeripheral จะจำลองอุปกรณ์ต่อพ่วงภายนอก: เซ็นเซอร์, ตัวติดตามฟิตเนส, บีคอน หรือเครื่องมือทางการแพทย์ อินสแตนซ์ CBPeripheral แต่ละตัวประกอบด้วยตัวระบุเฉพาะ (UUID) ซึ่งคงอยู่ระหว่างเซสชันการเชื่อมต่อ — Apple เชื่อมโยง UUID กับอุปกรณ์เฉพาะผ่านระบบ Bonding

CBPeripheral ไม่ได้ถูกสร้างขึ้นโดยตรงผ่าน init เฟรมเวิร์ก Core Bluetooth ส่งคืนวัตถุ CBPeripheral ในสองสถานการณ์: เมื่อค้นพบอุปกรณ์ผ่าน scanForPeripheralsWithServices: (ตัวแทน didDiscoverPeripheral) และเมื่อเชื่อมต่อกับอุปกรณ์ที่รู้จักก่อนหน้านี้ผ่าน retrievePeripheralsWithIdentifiers: หลังจากได้รับวัตถุ นักพัฒนาเรียก connectPeripheral: บน CBCentralManager หลังจากนั้น CBPeripheral จะพร้อมใช้งานสำหรับการดำเนินการ GATT

วงจรชีวิตของ CBPeripheral ประกอบด้วยหกสถานะ: ตัดการเชื่อมต่อ (เริ่มต้น), กำลังเชื่อมต่อ (หลังเรียก connect), เชื่อมต่อแล้ว (หลัง didConnectPeripheral), กำลังค้นพบ (ระหว่างเรียก discoverServices), ค้นพบแล้ว (หลังจากได้รับบริการ) และกำลังตัดการเชื่อมต่อ (หลัง cancelPeripheralConnection) แต่ละสถานะถูกติดตามผ่านโพรโทคอลตัวแทน CBPeripheralDelegate — สิ่งจำเป็นสำหรับแอปพลิเคชัน BLE บน iOS

CBPeripheral และลำดับชั้น GATT: บริการ คุณลักษณะ ตัวอธิบาย

CBPeripheral จัดเก็บโครงสร้าง GATT แบบลำดับชั้นที่ประกอบด้วยสามระดับ ระดับรากคืออาร์เรย์ของ CBService (บริการ), แต่ละบริการประกอบด้วยอาร์เรย์ของ CBCharacteristic (คุณลักษณะ), แต่ละคุณลักษณะประกอบด้วยอาร์เรย์ของ CBDescriptor (ตัวอธิบาย) โมเดลนี้สอดคล้องกับข้อกำหนด Bluetooth GATT อย่างสมบูรณ์: บริการคือฟังก์ชันของอุปกรณ์ (เช่น “บริการอัตราการเต้นของหัวใจ”), คุณลักษณะคือค่าเฉพาะ (ชีพจร 72 bpm), ตัวอธิบายคือเมตาดาต้าของคุณลักษณะ (หน่วยวัด, การกำหนดค่าการแจ้งเตือน)

ระดับคลาส Core Bluetoothคำอธิบาย
บริการCBServiceกลุ่มตรรกะของคุณลักษณะที่เกี่ยวข้อง ระบุโดย UUID (16-bit, 32-bit หรือ 128-bit)
คุณลักษณะCBCharacteristicค่าข้อมูลเฉพาะ รองรับการอ่าน การเขียน และการแจ้งเตือน
ตัวอธิบายCBDescriptorเมตาดาต้าของคุณลักษณะ: การกำหนดค่าไคลเอนต์ CCCD, คำอธิบายผู้ใช้, รูปแบบการนำเสนอ

บริการ BLE มาตรฐานถูกลงทะเบียนโดย Bluetooth SIG: Heart Rate Service (UUID 180D), Battery Service (180F), Device Information (180A), Blood Pressure (1810) สำหรับบริการที่กำหนดเอง จะใช้ UUID 128-bit (เช่น E20A39F4-73F5-4BC4-A12F-17D1AD07A961) iOS จะรู้จัก UUID มาตรฐานโดยอัตโนมัติและแสดงชื่อที่มนุษย์อ่านได้; UUID ที่กำหนดเองจะแสดงในรูปแบบเลขฐานสิบหก

หลังจากการเชื่อมต่อ ลำดับชั้นของ CBPeripheral จะว่างเปล่า — บริการและคุณลักษณะยังไม่ได้โหลด นักพัฒนาต้องเรียก discoverServices: เพื่อรับบริการ จากนั้นสำหรับแต่ละบริการเรียก discoverCharacteristics:forService: หากบริการมีบริการที่รวมอยู่ ให้เรียก discoverIncludedServices:forService: เพิ่มเติม เฉพาะเมื่อการค้นพบลำดับชั้นเสร็จสมบูรณ์ CBPeripheral จึงจะถูกเติมข้อมูลและพร้อมสำหรับการอ่านและการเขียน

การค้นพบบริการและคุณลักษณะ: เมธอดและตัวแทน

การค้นพบ โครงสร้าง GATT ของ CBPeripheral เป็นขั้นตอนบังคับก่อนการดำเนินการอ่านหรือเขียนใดๆ เมธอด discoverServices: เริ่มการค้นหาแบบอะซิงโครนัสของบริการทั้งหมดของอุปกรณ์ หากส่ง nil, บริการทั้งหมดจะถูกค้นพบ; หากส่งอาร์เรย์ของ CBUUID — เฉพาะบริการที่มี UUID ที่ระบุ (การเพิ่มประสิทธิภาพเวลา) ผลลัพธ์มาถึงตัวแทน peripheral:didDiscoverServices: — วัตถุ CBPeripheral เติมคุณสมบัติ services ด้วยอาร์เรย์ของ CBService

หลังจากได้รับบริการ สำหรับแต่ละ CBService จำเป็นต้องเรียก discoverCharacteristics:forService: ในทำนองเดียวกัน nil — คุณลักษณะทั้งหมด, อาร์เรย์ของ CBUUID — เฉพาะที่ระบุ ผลลัพธ์: peripheral:didDiscoverCharacteristicsForService:error: ในขั้นตอนนี้ CBCharacteristic จะได้รับคุณสมบัติ (properties: .read, .write, .notify, .indicate) ซึ่งกำหนดการดำเนินการที่อนุญาต

swift
import CoreBluetooth

extension BLEViewController: CBPeripheralDelegate {

    // 1. Service discovery
    func peripheral(_ peripheral: CBPeripheral,
                     didDiscoverServices error: Error?) {
        guard let services = peripheral.services else { return }

        for service in services {
            // Request characteristics for each service
            peripheral.discoverCharacteristics(nil, for: service)
        }
    }

    // 2. Characteristic discovery
    func peripheral(_ peripheral: CBPeripheral,
                     didDiscoverCharacteristicsFor service: CBService,
                     error: Error?) {
        guard let characteristics = service.characteristics else { return }

        for characteristic in characteristics {
            if characteristic.properties.contains(.read) {
                peripheral.readValue(for: characteristic)
            }
            if characteristic.properties.contains(.notify) {
                peripheral.setNotifyValue(true, for: characteristic)
            }
        }
    }

    // 3. Read value
    func peripheral(_ peripheral: CBPeripheral,
                     didUpdateValueFor characteristic: CBCharacteristic,
                     error: Error?) {
        guard let data = characteristic.value,
              let value = String(data: data, encoding: .utf8)
        else { return }
        print("Characteristic value: \(value)")
    }
}

ในตัวอย่าง CBPeripheralDelegate ใช้เมธอดการค้นพบสามรายการที่บังคับ didDiscoverServices วนซ้ำบริการทั้งหมดที่พบและขอคุณลักษณะ didDiscoverCharacteristicsForService ตรวจสอบคุณสมบัติของคุณลักษณะแต่ละรายการ: สำหรับ .read เรียก readValue, สำหรับ .notify เรียก setNotifyValue(true) เมธอด didUpdateValueForCharacteristic รับค่าจริงในรูปแบบ Data

การอ่านและการเขียนคุณลักษณะ: withResponse และ withoutResponse

การอ่านค่า ของ CBCharacteristic ดำเนินการโดยใช้เมธอด readValueForCharacteristic: ผลลัพธ์มาถึงแบบอะซิงโครนัสใน peripheral:didUpdateValueForCharacteristic:error: สำคัญ: อุปกรณ์อาจมีค่าในแคช (characteristic.value พร้อมใช้งานทันทีหลังการค้นพบ) แต่เพื่อรับข้อมูลปัจจุบัน การเรียก readValue เป็นสิ่งบังคับ iOS อาจแคชค่าเพื่อประสิทธิภาพการใช้พลังงาน — readValue รีเฟรชแคช

การเขียนค่า ดำเนินการโดยใช้เมธอด writeValue:forCharacteristic:type: พารามิเตอร์ type กำหนดประเภทการเขียน: .withResponse (CBCharacteristicWriteWithResponse) — อุปกรณ์ยืนยันการเขียนผ่าน didWriteValueForCharacteristic; .withoutResponse (CBCharacteristicWriteWithoutResponse) — การเขียนโดยไม่มีการยืนยัน ความเร็วสูงสุดแต่ไม่รับประกันการส่ง ข้อกำหนด BLE จำกัด MTU (หน่วยส่งสูงสุด): สูงสุด 23 ไบต์สำหรับ BLE 4.0, สูงสุด 251 ไบต์สำหรับ BLE 5.0+ สำหรับข้อมูลที่ใหญ่กว่า MTU จำเป็นต้องมีการแยกส่วนในระดับแอปพลิเคชัน

swift
// CBPeripheral characteristic read and write
class BLEService {

    private let peripheral: CBPeripheral
    private let serviceUUID = CBUUID(string: "180D")
    private let charUUID = CBUUID(string: "2A37")

    init(peripheral: CBPeripheral) {
        self.peripheral = peripheral
    }

    // Read with response
    func readHeartRate() {
        guard let service = peripheral.services?.first(where: { $0.uuid == serviceUUID }),
              let characteristic = service.characteristics?.first(where: { $0.uuid == charUUID })
        else { return }
        peripheral.readValue(for: characteristic)
    }

    // Write with response (withResponse)
    func writeWithResponse(data: Data) {
        guard let characteristic = findCharacteristic() else { return }
        peripheral.writeValue(data, for: characteristic,
                             type: .withResponse)
    }

    // Write without response (withoutResponse)
    // Max throughput, no delivery guarantee
    func writeWithoutResponse(data: Data) {
        guard let characteristic = findCharacteristic() else { return }
        peripheral.writeValue(data, for: characteristic,
                             type: .withoutResponse)
    }

    private func findCharacteristic() -> CBCharacteristic? {
        return peripheral.services?
            .flatMap { $0.characteristics ?? [] }
            .first(where: { $0.uuid == charUUID })
    }
}

การเลือกประเภทการเขียน withResponse หรือ withoutResponse ขึ้นอยู่กับข้อกำหนดความน่าเชื่อถือ สำหรับคำสั่ง (เปิดไฟ, ปลดล็อก) ใช้ withResponse — การรับประกันการส่งมีความสำคัญ สำหรับข้อมูลสตรีมมิ่ง (ชีพจร, อุณหภูมิ) ใช้ withoutResponse — การสูญเสียแพ็กเก็ตหนึ่งไม่สำคัญ อุปกรณ์ BLE อาจรองรับการเขียนเพียงประเภทเดียว — ตรวจสอบคุณสมบัติ characteristic.properties.contains(.write) และ .writeWithoutResponse

การสมัครรับการแจ้งเตือน BLE ผ่าน setNotifyValue

การแจ้งเตือน เป็นกลไก BLE ที่อุปกรณ์ต่อพ่วงส่งค่าคุณลักษณะไปยังอุปกรณ์กลางแบบอะซิงโครนัส โดยไม่ต้องสอบถามอย่างต่อเนื่องจากฝ่ายกลาง CBPeripheral เปิดใช้งานการสมัครรับข้อมูลผ่านเมธอด setNotifyValue:forCharacteristic: หลังจากเปิดใช้งานการสมัคร iOS จะเขียนลงใน CCCD (ตัวอธิบายการกำหนดค่าคุณลักษณะไคลเอนต์) บนอุปกรณ์ต่อพ่วงโดยอัตโนมัติ และอุปกรณ์เริ่มส่งการอัปเดตทุกครั้งที่มีการเปลี่ยนแปลงค่า

ต่างจากการบอก (indications), การแจ้งเตือน ไม่ต้องการการยืนยันจากอุปกรณ์กลาง — แพ็กเก็ตถูกส่งและถูกลืม สิ่งนี้ให้ปริมาณงานสูงสุด แต่แพ็กเก็ตอาจสูญหายได้ การบอกต้องการการยืนยันในระดับโพรโทคอล (L2CAP) — เชื่อถือได้มากกว่าแต่ช้ากว่า คุณสมบัติ properties ของ CBCharacteristic บ่งชี้อย่างแม่นยำว่ารองรับโหมดใด: .notify, .indicate หรือทั้งสองอย่าง

เมื่อ CBPeripheral ตัดการเชื่อมต่อ (ตัดการเชื่อมต่อ, อยู่นอกระยะ) การสมัครที่ใช้งานอยู่ทั้งหมดจะถูกรีเซ็ตโดยอัตโนมัติ เมื่อเชื่อมต่อใหม่ ต้องเรียก setNotifyValue:true อีกครั้งสำหรับแต่ละคุณลักษณะ iOS ยังสูญเสียการสมัครเมื่อแอปพลิเคชันออกจากเบื้องหน้า (หากไม่ได้เปิดใช้งานโหมดพื้นหลัง) — สำหรับการทำงานในพื้นหลัง ต้องเปิดใช้งานความสามารถ “Uses Bluetooth LE accessories” ใน Info.plist

swift
// CBPeripheral notification subscription management
class NotificationManager: NSObject {

    private var peripheral: CBPeripheral?
    private var subscribedCharacteristics: Set<CBUUID> = []

    // Subscribe to notifications for all .notify characteristics
    func subscribeToAllNotifications(peripheral: CBPeripheral) {
        self.peripheral = peripheral

        guard let services = peripheral.services else { return }

        for service in services {
            guard let characteristics = service.characteristics else { continue }

            for characteristic in characteristics {
                if characteristic.properties.contains(.notify)
                    || characteristic.properties.contains(.indicate) {
                    peripheral.setNotifyValue(true, for: characteristic)
                    subscribedCharacteristics.insert(characteristic.uuid)
                }
            }
        }
    }

    // Unsubscribe from all notifications
    func unsubscribeFromAll() {
        guard let peripheral = peripheral else { return }
        guard let services = peripheral.services else { return }

        for service in services {
            guard let characteristics = service.characteristics else { continue }

            for characteristic in characteristics {
                if subscribedCharacteristics.contains(characteristic.uuid) {
                    peripheral.setNotifyValue(false, for: characteristic)
                }
            }
        }
        subscribedCharacteristics.removeAll()
    }

    // Notification handler
    func peripheral(_ peripheral: CBPeripheral,
                     didUpdateNotificationStateFor characteristic: CBCharacteristic,
                     error: Error?) {
        if characteristic.isNotifying {
            print("Subscription active: \(characteristic.uuid)")
        } else {
            print("Subscription inactive: \(characteristic.uuid)")
        }
    }
}

NotificationManager แสดงการจัดการการแจ้งเตือน CBPeripheral ที่ถูกต้อง subscribeToAllNotifications วนซ้ำบริการและคุณลักษณะทั้งหมด โดยเปิดใช้งาน .notify และ .indicate subscribedCharacteristics ติดตามการสมัครที่ใช้งานอยู่เพื่อยกเลิกการสมัครอย่างเหมาะสม didUpdateNotificationStateForCharacteristic ยืนยันการเปลี่ยนแปลงสถานะการสมัครที่สำเร็จผ่านคุณสมบัติ characteristic.isNotifying

ตัวอย่าง CBPeripheral ที่สมบูรณ์ใน Swift

เวิร์กโฟลว์ที่สมบูรณ์ กับ CBPeripheral รวมถึง: การรับวัตถุจาก CBCentralManager, การเชื่อมต่อ, การค้นพบ, การอ่าน/เขียน, การสมัครรับการแจ้งเตือนและการตัดการเชื่อมต่อ ตัวอย่างด้านล่างใช้คลาส BLEConnection ที่จัดการวงจรชีวิตอุปกรณ์ต่อพ่วง BLE ที่สมบูรณ์ใน Swift โดยใช้ API async/await ที่ทันสมัย (iOS 15+)

swift
import CoreBluetooth

// Full CBPeripheral management example with async/await
class BLEConnection: NSObject {

    private let centralManager: CBCentralManager
    private var peripheral: CBPeripheral?
    private var continuation: CheckedContinuation<Void, Error>?

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

    // 1. Connect to peripheral
    func connect(to peripheral: CBPeripheral) async throws {
        self.peripheral = peripheral
        peripheral.delegate = self
        centralManager.connect(peripheral, options: nil)

        try await withCheckedThrowingContinuation { continuation in
            self.continuation = continuation
        }
    }

    // 2. Discovery  
    func discoverServices() async throws {
        guard let peripheral = peripheral else {
            throw BLEError.notConnected
        }
        peripheral.discoverServices(nil)
        try await withCheckedThrowingContinuation { continuation in
            self.continuation = continuation
        }
    }
}

// 3.  CBCentralManager
extension BLEConnection: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        // Handle Bluetooth device state
    }

    func centralManager(_ central: CBCentralManager,
                        didConnect peripheral: CBPeripheral) {
        continuation?.resume()
        continuation = nil
    }

    func centralManager(_ central: CBCentralManager,
                        didFailToConnect peripheral: CBPeripheral,
                        error: Error?) {
        continuation?.resume(throwing: error ?? BLEError.connectionFailed)
        continuation = nil
    }
}

enum BLEError: Error {
    case notConnected
    case connectionFailed
    case serviceNotFound
    case characteristicNotFound
}

คลาส BLEConnection ใช้ Swift Concurrency (async/await) ผ่าน CheckedContinuation — รูปแบบที่ทันสมัยสำหรับทำงานกับ API ที่ใช้ตัวแทนของ Core Bluetooth connect(to:) รอการยืนยันการเชื่อมต่อผ่าน didConnectPeripheral, discoverServices() — ผ่าน didDiscoverServices วิธีการนี้กำจัดตัวแทนที่ซ้อนกันและทำให้โค้ด BLE เป็นเชิงเส้นและอ่านง่าย การจัดการข้อผิดพลาดผ่าน BLEError ครอบคลุมสถานการณ์ความล้มเหลวของการเชื่อมต่อ BLE ทั่วไปทั้งหมด

คำถามที่พบบ่อย

วิธีรับ CBPeripheral โดยไม่ต้องสแกน?

CBPeripheral สำหรับอุปกรณ์ที่เชื่อมต่อก่อนหน้านี้สามารถรับได้ผ่าน retrievePeripheralsWithIdentifiers: บน CBCentralManager ส่งอาร์เรย์ของ UUID (NSUUID) ของอุปกรณ์ที่บันทึกไว้ก่อนหน้านี้ — เฟรมเวิร์กส่งคืนอาร์เรย์ของ CBPeripheral สำหรับอุปกรณ์ในฐานข้อมูลการเชื่อมโยง BLE ของระบบ วิธีนี้ใช้ได้เฉพาะกับอุปกรณ์ที่ iPhone จับคู่มาก่อน สำหรับอุปกรณ์ใหม่ การสแกนเป็นสิ่งจำเป็น

ทำไม CBPeripheral ถึงไม่ค้นพบบริการ?

สาเหตุทั่วไป: อุปกรณ์อยู่นอกระยะ (RSSI ต่ำกว่าเกณฑ์), วิทยุ BLE ปิดอยู่ (CBCentralManager.state != .poweredOn), ตัวแทน CBPeripheralDelegate ไม่ได้ตั้งค่า (peripheral.delegate = self), หรือเรียก discoverServices ก่อนการเชื่อมต่อ ตรวจสอบ centralManager.state, ตรวจสอบให้แน่ใจว่าตั้งค่าตัวแทนก่อนเรียก connect และใช้การลองใหม่ด้วยการหมดเวลา 5–10 วินาที

จะทำอย่างไรถ้า writeValue ไม่ตอบสนอง?

สาเหตุคือการใช้ .withResponse กับคุณลักษณะที่รองรับเฉพาะ .writeWithoutResponse หรือกลับกัน ตรวจสอบ characteristic.properties ก่อนเรียก ปัญหาอื่นที่อาจเกิดขึ้นคือ MTU: หากข้อมูลเกิน 20 ไบต์ (MTU BLE 4.0) จำเป็นต้องเจรจา MTU ผ่าน negotiateMTU หรือการแยกส่วน ใช้ peripheral.maximumWriteValueLength(for: .withResponse) เพื่อกำหนดขนาดแพ็กเก็ตสูงสุด

วิธีแยกแยะ CBPeripheral ในระยะจากที่ไม่มีให้ใช้?

CBPeripheral ที่อยู่นอกระยะไม่ได้ตัดการเชื่อมต่อทันที — iOS เปลี่ยนเป็นสถานะ .disconnected หลังจากหมดเวลา (โดยปกติ 20–30 วินาที) สำหรับการตรวจสอบ ใช้ readRSSI บน CBPeripheral — หากไม่มีให้ใช้ จะส่งคืนข้อผิดพลาดด้วยรหัส CBError.connectionTimeout ตรวจสอบ centralManager:didDisconnectPeripheral:error: เพื่อตรวจจับการสูญเสียการเชื่อมต่อได้ทันท่วงที

สามารถใช้ CBPeripheral เดียวจากหลายเธรดได้หรือไม่?

Core Bluetooth ไม่ปลอดภัยต่อเธรด — การเรียก CBPeripheral ทั้งหมดต้องทำจากคิวเดียวกัน (โดยปกติคือคิวหลักหรือคิวแบบอนุกรมที่ระบุเมื่อเริ่มต้น CBCentralManager) การเรียกพร้อมกันจากเธรดต่างกันทำให้เกิด race condition และแอปพลิเคชันขัดข้อง ใช้ DispatchQueue(label: “com.app.ble”) สำหรับการดำเนินการ BLE ทั้งหมดและ DispatchQueue.main.async สำหรับการอัปเดต UI

สรุป

  • CBPeripheral เป็นคลาส Core Bluetooth สำหรับทำงานกับอุปกรณ์ BLE ระยะไกลบน iOS ส่งคืนโดย CBCentralManager
  • ลำดับชั้น GATT ประกอบด้วยบริการ (CBService), คุณลักษณะ (CBCharacteristic) และตัวอธิบาย (CBDescriptor) พร้อม UUID 16-bit หรือ 128-bit
  • การค้นพบ ดำเนินการตามลำดับ: discoverServices: → discoverCharacteristics:forService: พร้อมการจัดการผ่านตัวแทน
  • การอ่าน — readValueForCharacteristic:, การเขียน — writeValue:forCharacteristic:type: (.withResponse หรือ .withoutResponse)
  • การแจ้งเตือน — setNotifyValue:forCharacteristic: เปิดใช้งานการส่งข้อมูลแบบอะซิงโครนัสจากอุปกรณ์ต่อพ่วงไปยังศูนย์กลาง
  • MTU สำหรับ BLE 4.0 จำกัดแพ็กเก็ตที่ 23 ไบต์, BLE 5.0+ — สูงสุด 251 ไบต์, ข้อมูลที่เกิน MTU ต้องการการแยกส่วน
  • Swift async/await ผ่าน CheckedContinuation ทำให้โค้ด BLE ง่ายขึ้น แทนที่ตัวแทนที่ซ้อนกันด้วยการเรียกเชิงเส้น

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม