技能誌

感測器 UI Demo

資訊/科技
奧提斯的頭像
奧提斯
更新日:2025年4月22日

看了前幾篇,應該有人會好奇在iPhone 上呈現會是什麼樣子呢,這裡提供一些簡易的範本,有興趣的朋友可以照著步驟試試看,說不定你也會一頭栽進BLE的世界喔。


SwiftUI + CoreBluetooth 的基本範例專案,功能是:

✅ 掃描並連線到你的 Nordic DK 開發板

✅ 讀取一個感測器特徵值(例如溫度)

✅ 即時顯示資料在畫面上


📦 專案結構概覽

BLESensorApp/
├── ContentView.swift        # SwiftUI 主畫面
├── BluetoothManager.swift   # CoreBluetooth 邏輯集中處理
└── Models/
    └── SensorData.swift     # 感測資料模型(可選)


1. BluetoothManager.swift

import CoreBluetooth
import Foundation

class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate {

  @Published var temperature: Double = 0.0

  @Published var isConnected = false

  private var centralManager: CBCentralManager!

  private var peripheral: CBPeripheral?

  // 替換成你的 Service 與 Characteristic UUID

  private let sensorServiceUUID = CBUUID(string: "XXXX")

  private let temperatureCharUUID = CBUUID(string: "YYYY")

  override init() {

    super.init()

    centralManager = CBCentralManager(delegate: self, queue: nil)

  }

  // MARK: - CBCentralManagerDelegate

  func centralManagerDidUpdateState(_ central: CBCentralManager) {

    if central.state == .poweredOn {

      central.scanForPeripherals(withServices: [sensorServiceUUID], options: nil)

    }

  }

  func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,

            advertisementData: [String : Any], rssi RSSI: NSNumber) {

    self.peripheral = peripheral

    self.peripheral?.delegate = self

    centralManager.stopScan()

    centralManager.connect(peripheral, options: nil)

  }

  func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

    isConnected = true

    peripheral.discoverServices([sensorServiceUUID])

  }

  // MARK: - CBPeripheralDelegate

  func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

    guard let services = peripheral.services else { return }

    for service in services {

      peripheral.discoverCharacteristics([temperatureCharUUID], for: service)

    }

  }

  func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService,

          error: Error?) {

    guard let characteristics = service.characteristics else { return }

    for char in characteristics {

      if char.uuid == temperatureCharUUID {

        peripheral.setNotifyValue(true, for: char)

      }

    }

  }

  func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic,

          error: Error?) {

    guard let data = characteristic.value else { return }

    // 假設溫度是 1 byte 的 UInt8 數值

    let temp = Double(data.first ?? 0)

    DispatchQueue.main.async {

      self.temperature = temp

    }

  }
}



🖼 2. ContentView.swift

import SwiftUI

struct ContentView: View {

  @StateObject private var bluetoothManager = BluetoothManager()

  var body: some View {

    VStack(spacing: 20) {

      Text(bluetoothManager.isConnected ? "✅ 已連線" : "🔍 掃描中…")

        .font(.headline)

      Text("🌡️ 溫度:\(bluetoothManager.temperature, specifier: "%.1f") °C")

        .font(.largeTitle)

        .bold()

      Spacer()
    }
    .padding()

  }

}


🧪 注意事項

你需要把 sensorServiceUUID 和 temperatureCharUUID 替換成你 Nordic 開發板廣播的 UUID。


若特徵值是 2 bytes 或 Float32,就要修改 didUpdateValueFor 解析的方式。

iOS App 客製化 上架。
iOS 軟體開發、修改、維護既有App
IT/程式 > iPhone/iPad/Mac應用程式開發
$ 10000
iOS App 客製化 上架。
$ 10000
iOS App 客製化 上架。
0 / 1000
回到文章列表