feat: Buttons for LED on and off
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"swiftPM": {
|
||||
"swiftSDK": "arm64-apple-ios"
|
||||
"swiftSDK": "darwin"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,7 @@
|
||||
<string>This app uses Bluetooth to connect to the collar tag.</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>This app uses Bluetooth to connect to the collar tag.</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array><string>bluetooth-central</string></array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -6,7 +6,6 @@ let package = Package(
|
||||
name: "ScoobyTag",
|
||||
platforms: [
|
||||
.iOS(.v15),
|
||||
.macOS(.v14),
|
||||
],
|
||||
products: [
|
||||
// An xtool project should contain exactly one library product,
|
||||
|
||||
@@ -8,12 +8,39 @@ struct Constants {
|
||||
|
||||
final class BluetoothManager: NSObject, ObservableObject {
|
||||
private var centralManager: CBCentralManager!
|
||||
private var myPeripheral: CBPeripheral?
|
||||
private var tagPerihp: CBPeripheral?
|
||||
private var scbtSvc: CBService?
|
||||
private var petChar: CBCharacteristic?
|
||||
@Published var status = "Starting..."
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
periphManager = CBPeripheralManager(delegate: self, queue: nil)
|
||||
centralManager = CBCentralManager(
|
||||
delegate: self,
|
||||
queue: nil,
|
||||
//options: [
|
||||
// CBCentralManagerOptionRestoreIdentifierKey: "DogCollarCentral"
|
||||
//]
|
||||
)
|
||||
}
|
||||
|
||||
func led_on() {
|
||||
pet_write(0)
|
||||
}
|
||||
|
||||
func led_off() {
|
||||
pet_write(1)
|
||||
}
|
||||
|
||||
func pet_write(_ value: UInt32) {
|
||||
if tagPerihp == nil || petChar == nil {
|
||||
status = "Not connected!"
|
||||
return
|
||||
}
|
||||
|
||||
var lvalue = value
|
||||
let data = Data(bytes: &lvalue, count: MemoryLayout<UInt32>.size)
|
||||
tagPerihp!.writeValue(data, for: petChar!, type: .withResponse)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +67,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
advertisementData: [String: Any],
|
||||
rssi RSSI: NSNumber
|
||||
) {
|
||||
if (peripheral.name != nil) {
|
||||
status = "Found: \(peripheral.name!)"
|
||||
} else {
|
||||
status = "Found: \(peripheral.identifier)"
|
||||
}
|
||||
|
||||
myPeripheral = peripheral
|
||||
let name = peripheral.name ?? peripheral.identifier.uuidString
|
||||
status = "Found \(name)"
|
||||
tagPerihp = peripheral
|
||||
central.stopScan()
|
||||
central.connect(peripheral)
|
||||
}
|
||||
@@ -56,7 +79,8 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
_ central: CBCentralManager,
|
||||
didConnect peripheral: CBPeripheral
|
||||
) {
|
||||
status = "Connected"
|
||||
let name = peripheral.name ?? peripheral.identifier.uuidString
|
||||
status = "Connected to \(name)"
|
||||
let uuid = CBUUID(string: Constants.scbtSvcUuid)
|
||||
peripheral.discoverServices([uuid])
|
||||
peripheral.delegate = self
|
||||
@@ -72,6 +96,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
if (error == nil) { error2 = "unknown" }
|
||||
else { error2 = "\(error!)" }
|
||||
status = "Failed: \(error2)"
|
||||
|
||||
tagPerihp = nil
|
||||
petChar = nil
|
||||
}
|
||||
|
||||
// Disconnection callback
|
||||
@@ -84,6 +111,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
if (error == nil) { error2 = "unknown" }
|
||||
else { error2 = "\(error!)" }
|
||||
status = "Disconnected: \(error2)"
|
||||
|
||||
tagPerihp = nil
|
||||
petChar = nil
|
||||
}
|
||||
|
||||
// Service callback
|
||||
@@ -93,16 +123,18 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
) {
|
||||
guard let services = peripheral.services else { return }
|
||||
|
||||
status = "Service found"
|
||||
|
||||
let scbtSvc = CBUUID(string: Constants.scbtSvcUuid)
|
||||
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
|
||||
let svcUUID = CBUUID(string: Constants.scbtSvcUuid)
|
||||
let petUUID = CBUUID(string: Constants.scbtPetUuid)
|
||||
|
||||
for service in services {
|
||||
// Ignore non scbtSvc
|
||||
if (service.uuid != scbtSvc) { continue }
|
||||
if (service.uuid == svcUUID) {
|
||||
scbtSvc = service
|
||||
peripheral.discoverCharacteristics([petUUID], for: service)
|
||||
}
|
||||
}
|
||||
|
||||
peripheral.discoverCharacteristics([scbtPet], for: service)
|
||||
if scbtSvc == nil {
|
||||
status = "Could not find scbt service"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,20 +150,17 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
}
|
||||
|
||||
guard let characteristics = service.characteristics else { return }
|
||||
|
||||
status = "Characteristics found (\(characteristics.count))"
|
||||
|
||||
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
|
||||
|
||||
for characteristic in characteristics {
|
||||
// Ignore non pet
|
||||
if (characteristic.uuid != scbtPet) { continue }
|
||||
for characteristic: CBCharacteristic in characteristics {
|
||||
if (characteristic.uuid == scbtPet) {
|
||||
petChar = characteristic
|
||||
status = "Found pet characteristic"
|
||||
}
|
||||
}
|
||||
|
||||
var value: UInt32 = 0
|
||||
let data = Data(bytes: &value, count: MemoryLayout<UInt32>.size)
|
||||
|
||||
perihperal.writeValue(data, for: characteristic, type: .withResponse)
|
||||
status = "Written \(data)"
|
||||
if petChar == nil {
|
||||
status = "Could not find pet characteristic"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,15 @@ struct ContentView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Image(systemName: "globe")
|
||||
.imageScale(.large)
|
||||
.foregroundStyle(.tint)
|
||||
Text("Hello, world!")
|
||||
Text(bluetoothManager.status)
|
||||
Button(action: bluetoothManager.led_on) {
|
||||
Text("LED On")
|
||||
}
|
||||
Button(action: bluetoothManager.led_off) {
|
||||
Text("LED Off")
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.buttonStyle(BorderedButtonStyle())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user