Tüm Yazılar
KategoriiOS
Okuma Süresi
21 dk
Yayın Tarihi
...
Kelime Sayısı
1.217kelime

Kahveni hazırla - bu içerikli bir makale!

Bluetooth Low Energy ile IoT cihaz iletişimi. CBCentralManager, peripheral keşfi, servis/karakteristik okuma, background BLE ve state restoration.

Core Bluetooth ve BLE: IoT Cihazlarla İletişim Rehberi

IoT cihazlar hayatımızın her yerinde — akıllı saatler, fitness bileklikleri, akıllı ev cihazları, sağlık sensörleri. Bu cihazların çoğu Bluetooth Low Energy (BLE) ile iletişim kurar. Core Bluetooth framework'ü, iOS uygulamalarının bu cihazlarla konuşmasını sağlar.

💡 Hızlı Not: BLE, Bluetooth 4.0 ile tanıtıldı ve klasik Bluetooth'tan çok daha az enerji tüketir. iPhone 4S'ten bu yana tüm iOS cihazlar BLE destekler.

İçindekiler

  1. BLE Temel Kavramlar
  2. Central vs Peripheral Rolleri
  3. CBCentralManager ile Tarama
  4. Servis ve Karakteristik Keşfi
  5. Veri Okuma ve Yazma
  6. Notifications ile Gerçek Zamanlı Veri
  7. CBPeripheralManager ile Yayın
  8. Background BLE
  9. State Restoration
  10. Debugging ve Test

BLE Temel Kavramlar {#ble-temeller}

Kavram
Açıklama
Örnek
Central
Veri talep eden (iPhone)
Uygulamanız
Peripheral
Veri sunan (sensör)
Kalp atış sensörü
Service
Fonksiyon grubu (UUID)
Heart Rate Service
Characteristic
Tek veri noktası
Heart Rate Measurement
Descriptor
Karakteristik metadata'sı
Client Configuration
GATT
Generic Attribute Profile
BLE iletişim protokolü

Central vs Peripheral Rolleri {#central-peripheral}

swift
1// Central rolü - cihaz tarayan ve bağlanan taraf
2// Peripheral rolü - veri yayınlayan ve sunan taraf
3 
4// Tipik akış:
5// 1. Central tarama başlatır (scan for peripherals)
6// 2. Peripheral reklam yayınlar (advertise)
7// 3. Central peripheral'ı keşfeder
8// 4. Bağlantı kurulur (connect)
9// 5. Servisler ve karakteristikler keşfedilir (discover)
10// 6. Veri okunur/yazılır (read/write)
11// 7. Notification'lara abone olunur (subscribe)

CBCentralManager ile Tarama {#central-manager}

swift
1import CoreBluetooth
2 
3class BLEManager: NSObject, ObservableObject {
4 private var centralManager: CBCentralManager!
5 @Published var discoveredPeripherals: [CBPeripheral] = []
6 @Published var connectedPeripheral: CBPeripheral?
7 @Published var isScanning = false
8 
9 override init() {
10 super.init()
11 centralManager = CBCentralManager(delegate: self, queue: nil)
12 }
13 
14 func startScanning() {
15 guard centralManager.state == .poweredOn else { return }
16 isScanning = true
17 // Belirli service UUID'ye göre tara
18 centralManager.scanForPeripherals(
19 withServices: [CBUUID(string: "180D")], // Heart Rate Service
20 options: [CBCentralManagerScanOptionAllowDuplicatesKey: false]
21 )
22 // 10 saniye sonra taramayı durdur
23 DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in
24 self?.stopScanning()
25 }
26 }
27 
28 func stopScanning() {
29 centralManager.stopScan()
30 isScanning = false
31 }
32 
33 func connect(_ peripheral: CBPeripheral) {
34 centralManager.connect(peripheral, options: nil)
35 }
36}
37 
38extension BLEManager: CBCentralManagerDelegate {
39 func centralManagerDidUpdateState(_ central: CBCentralManager) {
40 switch central.state {
41 case .poweredOn: print("Bluetooth açık")
42 case .poweredOff: print("Bluetooth kapalı")
43 case .unauthorized: print("İzin gerekli")
44 default: break
45 }
46 }
47 
48 func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
49 advertisementData: [String: Any], rssi RSSI: NSNumber) {
50 if !discoveredPeripherals.contains(peripheral) {
51 discoveredPeripherals.append(peripheral)
52 }
53 }
54 
55 func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
56 connectedPeripheral = peripheral
57 peripheral.delegate = self
58 peripheral.discoverServices(nil) // Tüm servisleri keşfet
59 }
60}

Servis ve Karakteristik Keşfi {#servis-kesfi}

swift
1extension BLEManager: CBPeripheralDelegate {
2 func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
3 guard let services = peripheral.services else { return }
4 for service in services {
5 print("Service: \(service.uuid)")
6 peripheral.discoverCharacteristics(nil, for: service)
7 }
8 }
9 
10 func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
11 guard let characteristics = service.characteristics else { return }
12 for characteristic in characteristics {
13 print(" Characteristic: \(characteristic.uuid), properties: \(characteristic.properties)")
14 
15 if characteristic.properties.contains(.read) {
16 peripheral.readValue(for: characteristic)
17 }
18 if characteristic.properties.contains(.notify) {
19 peripheral.setNotifyValue(true, for: characteristic)
20 }
21 }
22 }
23}

Veri Okuma ve Yazma {#veri-okuma-yazma}

swift
1// Okuma
2func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
3 guard let data = characteristic.value else { return }
4 
5 switch characteristic.uuid {
6 case CBUUID(string: "2A37"): // Heart Rate Measurement
7 let heartRate = parseHeartRate(data)
8 DispatchQueue.main.async {
9 self.currentHeartRate = heartRate
10 }
11 case CBUUID(string: "2A19"): // Battery Level
12 let battery = data.first ?? 0
13 print("Battery: \(battery)%")
14 default:
15 break
16 }
17}
18 
19// Yazma
20func sendCommand(_ command: Data, to characteristic: CBCharacteristic) {
21 guard let peripheral = connectedPeripheral else { return }
22 
23 if characteristic.properties.contains(.writeWithoutResponse) {
24 peripheral.writeValue(command, for: characteristic, type: .withoutResponse)
25 } else {
26 peripheral.writeValue(command, for: characteristic, type: .withResponse)
27 }
28}
29 
30// Heart rate parsing
31private func parseHeartRate(_ data: Data) -> Int {
32 let flags = data[0]
33 let is16Bit = (flags & 0x01) == 1
34 if is16Bit {
35 return Int(data[1]) | (Int(data[2]) << 8)
36 } else {
37 return Int(data[1])
38 }
39}

Notifications ile Gerçek Zamanlı Veri {#notifications}

Notification'a abone olarak, karakteristik değeri değiştiğinde otomatik güncelleme alırsın. setNotifyValue(true, for: characteristic) çağrısı yeterli — delegate'deki didUpdateValueFor callback'i otomatik tetiklenir.

CBPeripheralManager ile Yayın {#peripheral-manager}

iPhone'u BLE peripheral olarak da kullanabilirsin:

swift
1class BLEPeripheral: NSObject, CBPeripheralManagerDelegate {
2 private var peripheralManager: CBPeripheralManager!
3 private var transferCharacteristic: CBMutableCharacteristic?
4 
5 override init() {
6 super.init()
7 peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
8 }
9 
10 func startAdvertising() {
11 let service = CBMutableService(type: CBUUID(string: "FFF0"), primary: true)
12 let characteristic = CBMutableCharacteristic(
13 type: CBUUID(string: "FFF1"),
14 properties: [.read, .notify, .write],
15 value: nil,
16 permissions: [.readable, .writeable]
17 )
18 transferCharacteristic = characteristic
19 service.characteristics = [characteristic]
20 peripheralManager.add(service)
21 peripheralManager.startAdvertising([
22 CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: "FFF0")],
23 CBAdvertisementDataLocalNameKey: "MyDevice"
24 ])
25 }
26 
27 func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
28 if peripheral.state == .poweredOn { startAdvertising() }
29 }
30}

Background BLE {#background-ble}

Info.plist'te UIBackgroundModes altında bluetooth-central ve/veya bluetooth-peripheral ekleyerek arka planda BLE kullanabilirsin. Kısıtlamalar: tarama aralığı uzar, connection sayısı sınırlıdır.

State Restoration {#state-restoration}

swift
1// App terminate olsa bile BLE bağlantılarını geri yükle
2let centralManager = CBCentralManager(
3 delegate: self,
4 queue: nil,
5 options: [CBCentralManagerOptionRestoreIdentifierKey: "myCentral"]
6)
7 
8func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) {
9 if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] {
10 for peripheral in peripherals {
11 peripheral.delegate = self
12 connectedPeripheral = peripheral
13 }
14 }
15}

Debugging ve Test {#debugging}

  1. nRF Connect uygulaması ile BLE simülasyonu
  2. LightBlue ile karakteristik okuma/yazma test
  3. PacketLogger (Xcode Additional Tools) ile BLE paket analizi
  4. Console.app ile CoreBluetooth log'ları

Easter Egg

Gizli bir bilgi buldun!

Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

ALTIN İPUCU

Bu yazının en değerli bilgisi

Bu ipucu, yazının en önemli çıkarımını içeriyor.

Okuyucu Ödülü

Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var: **Kaynaklar:** - [Apple: Core Bluetooth](https://developer.apple.com/documentation/corebluetooth) - [WWDC17: What's New in Core Bluetooth](https://developer.apple.com/videos/play/wwdc2017/712/) - [Bluetooth SIG: GATT Services](https://www.bluetooth.com/specifications/specs/)

Etiketler

#bluetooth#ble#core-bluetooth#iot#peripheral#central#ios
Muhittin Çamdalı

Muhittin Çamdalı

Senior iOS Developer

12+ yıllık deneyime sahip iOS Developer. Swift, SwiftUI ve modern iOS mimarileri konusunda uzman. Apple platformlarında performanslı ve kullanıcı dostu uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

Bunu da begenebilirsiniz