diff --git a/RippleChat.xcodeproj/project.pbxproj b/RippleChat.xcodeproj/project.pbxproj index e7f903f..d138e43 100644 --- a/RippleChat.xcodeproj/project.pbxproj +++ b/RippleChat.xcodeproj/project.pbxproj @@ -19,13 +19,14 @@ 96BD33102A5C27B0007A6E53 /* NewFeedEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */; }; 96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33122A5C400B007A6E53 /* FeedListView.swift */; }; 96BD33162A5C403C007A6E53 /* PeeringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33152A5C403C007A6E53 /* PeeringView.swift */; }; - F581F59B2A5AE72F0081C383 /* BluetoothViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F581F59A2A5AE72F0081C383 /* BluetoothViewModel.swift */; }; + F581F59B2A5AE72F0081C383 /* BluetoothController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F581F59A2A5AE72F0081C383 /* BluetoothController.swift */; }; F5847B622A599BF4009E28D4 /* Body.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B612A599BF4009E28D4 /* Body.swift */; }; F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B632A599CC3009E28D4 /* LogEntry.swift */; }; F5847B662A599EA4009E28D4 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B652A599EA4009E28D4 /* Feed.swift */; }; F5847B6A2A59AB24009E28D4 /* FeedStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B692A59AB24009E28D4 /* FeedStore.swift */; }; F58EB2D02A5590E800E22DA6 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = F58EB2CF2A5590E800E22DA6 /* README.md */; }; F5A4B1212A5D4D1F00F5AE01 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5A4B1202A5D4D1F00F5AE01 /* SettingsView.swift */; }; + F5A4B1232A5D5F8B00F5AE01 /* BTPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5A4B1222A5D5F8B00F5AE01 /* BTPeripheral.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -61,13 +62,14 @@ 96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewFeedEntryView.swift; sourceTree = ""; }; 96BD33122A5C400B007A6E53 /* FeedListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListView.swift; sourceTree = ""; }; 96BD33152A5C403C007A6E53 /* PeeringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeeringView.swift; sourceTree = ""; }; - F581F59A2A5AE72F0081C383 /* BluetoothViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothViewModel.swift; sourceTree = ""; }; + F581F59A2A5AE72F0081C383 /* BluetoothController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothController.swift; sourceTree = ""; }; F5847B612A599BF4009E28D4 /* Body.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Body.swift; sourceTree = ""; }; F5847B632A599CC3009E28D4 /* LogEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogEntry.swift; sourceTree = ""; }; F5847B652A599EA4009E28D4 /* Feed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = ""; }; F5847B692A59AB24009E28D4 /* FeedStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedStore.swift; sourceTree = ""; }; F58EB2CF2A5590E800E22DA6 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; F5A4B1202A5D4D1F00F5AE01 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; + F5A4B1222A5D5F8B00F5AE01 /* BTPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPeripheral.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -123,7 +125,7 @@ 96454F1A2A558EBC0040BEBD /* RippleChatApp.swift */, 96454F1C2A558EBC0040BEBD /* ContentView.swift */, 96BD33112A5C3FFC007A6E53 /* Views */, - F581F59A2A5AE72F0081C383 /* BluetoothViewModel.swift */, + F581F59A2A5AE72F0081C383 /* BluetoothController.swift */, 96454F1E2A558EBD0040BEBD /* Assets.xcassets */, 96454F202A558EBD0040BEBD /* Preview Content */, F5847B612A599BF4009E28D4 /* Body.swift */, @@ -131,6 +133,7 @@ F5847B652A599EA4009E28D4 /* Feed.swift */, F5847B692A59AB24009E28D4 /* FeedStore.swift */, 96BD330D2A5C254B007A6E53 /* TextApp.swift */, + F5A4B1222A5D5F8B00F5AE01 /* BTPeripheral.swift */, ); path = RippleChat; sourceTree = ""; @@ -309,8 +312,9 @@ 96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */, F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */, 96BD33102A5C27B0007A6E53 /* NewFeedEntryView.swift in Sources */, + F5A4B1232A5D5F8B00F5AE01 /* BTPeripheral.swift in Sources */, F5847B6A2A59AB24009E28D4 /* FeedStore.swift in Sources */, - F581F59B2A5AE72F0081C383 /* BluetoothViewModel.swift in Sources */, + F581F59B2A5AE72F0081C383 /* BluetoothController.swift in Sources */, 96454F1D2A558EBC0040BEBD /* ContentView.swift in Sources */, F5A4B1212A5D4D1F00F5AE01 /* SettingsView.swift in Sources */, 96BD330E2A5C254B007A6E53 /* TextApp.swift in Sources */, diff --git a/RippleChat/BTPeripheral.swift b/RippleChat/BTPeripheral.swift new file mode 100644 index 0000000..0fe3a60 --- /dev/null +++ b/RippleChat/BTPeripheral.swift @@ -0,0 +1,68 @@ +// +// BTPeripheral.swift +// RippleChat +// +// Created by Severin Memmishofer on 11.07.23. +// + +import SwiftUI +import CoreBluetooth + +class BluetoothPeripheral: NSObject, ObservableObject { + + private var peripheralManager: CBPeripheralManager? + + let BLE_SERVICE_UUID = CBUUID(string: "6e400001-7646-4b5b-9a50-71becce51558") + let BLE_CHARACTERISTIC_UUID_RX = CBUUID(string: "6e400002-7646-4b5b-9a50-71becce51558") + + override init() { + super.init() + self.peripheralManager = CBPeripheralManager(delegate: self, queue: .main) + } +} + +extension BluetoothPeripheral: CBPeripheralManagerDelegate { + func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { + switch peripheral.state { + case .unknown: + print("Bluetooth Device is UNKNOWN") + case .unsupported: + print("Bluetooth Device is UNSUPPORTED") + case .unauthorized: + print("Bluetooth Device is UNAUTHORIZED") + case .resetting: + print("Bluetooth Device is RESETTING") + case .poweredOff: + print("Bluetooth Device is POWERED OFF") + case .poweredOn: + print("Bluetooth Device is POWERED ON") + addServices() + @unknown default: + fatalError() + } + } + + func addServices() { + + let value = Feed.sampleFeed + // let valueData = value(using: .utf8) + + // 1. Create instance of CBMutableCharcateristic +// let myCharacteristic1 = CBMutableCharacteristic(type: CBUUID(nsuuid: UUID()), properties: [.notify, .write, .read], value: nil, permissions: [.readable, .writeable]) + let myCharacteristic = CBMutableCharacteristic(type: BLE_CHARACTERISTIC_UUID_RX, properties: [.read], value: nil, permissions: [.readable]) + + // 2. Create instance of CBMutableService + let myService = CBMutableService(type: BLE_SERVICE_UUID, primary: true) + + // 3. Add characteristics to the service + myService.characteristics = [myCharacteristic] + + // 4. Add service to peripheralManager + peripheralManager!.add(myService) + + // 5. Start advertising + peripheralManager!.startAdvertising([CBAdvertisementDataLocalNameKey : "RippleChat", CBAdvertisementDataServiceUUIDsKey : BLE_SERVICE_UUID]) + print("Started Advertising") + + } +} diff --git a/RippleChat/BluetoothViewModel.swift b/RippleChat/BluetoothController.swift similarity index 72% rename from RippleChat/BluetoothViewModel.swift rename to RippleChat/BluetoothController.swift index 995eeba..e2aa63c 100644 --- a/RippleChat/BluetoothViewModel.swift +++ b/RippleChat/BluetoothController.swift @@ -1,5 +1,5 @@ // -// BluetoothViewModel.swift +// BluetoothController.swift // RippleChat // // Created by Severin Memmishofer on 09.07.23. @@ -8,21 +8,24 @@ import SwiftUI import CoreBluetooth -class BluetoothViewModel: NSObject, ObservableObject { +class BluetoothController: NSObject, ObservableObject { private var centralManager: CBCentralManager? private var peripherals: [CBPeripheral] = [] @Published var peripheralNames: [String] = [] + let BLE_SERVICE_UUID = CBUUID(string: "6e400001-7646-4b5b-9a50-71becce51558") + let BLE_CHARACTERISTIC_UUID_RX = CBUUID(string: "6e400002-7646-4b5b-9a50-71becce51558") + override init() { super.init() self.centralManager = CBCentralManager(delegate: self, queue: .main) } } -extension BluetoothViewModel: CBCentralManagerDelegate { +extension BluetoothController: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { - self.centralManager?.scanForPeripherals(withServices: nil) + self.centralManager?.scanForPeripherals(withServices: [BLE_SERVICE_UUID]) } } diff --git a/RippleChat/Views/PeeringView.swift b/RippleChat/Views/PeeringView.swift index 53f108f..79ff0ea 100644 --- a/RippleChat/Views/PeeringView.swift +++ b/RippleChat/Views/PeeringView.swift @@ -8,12 +8,13 @@ import SwiftUI struct PeeringView: View { - @ObservedObject private var bluetoothViewModel = BluetoothViewModel() + @ObservedObject private var bluetoothController = BluetoothController() + @ObservedObject private var bluetoothPeripheral = BluetoothPeripheral() var body: some View { Text("Peering View") NavigationView { - List(bluetoothViewModel.peripheralNames, id: \.self) { peripheral in + List(bluetoothController.peripheralNames, id: \.self) { peripheral in Text(peripheral) } .navigationTitle("Peripherals")