Skip to content

Commit

Permalink
Updated apis to be more unified in their behaviour. Improved the stru…
Browse files Browse the repository at this point in the history
…cture. (#147)

Added ability to scan filter and also auto detect services
  • Loading branch information
Reedyuk authored Nov 21, 2024
1 parent 4d21919 commit 899b954
Show file tree
Hide file tree
Showing 42 changed files with 627 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@
7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
87E4646B2B808845003F8CC1 /* ComposeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeView.swift; sourceTree = "<group>"; };
8E10DB932CB709D300862B82 /* BlueFalcon.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BlueFalcon.kt; sourceTree = "<group>"; };
8E10DB942CB709D300862B82 /* BluetoothCharacteristic.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothCharacteristic.kt; sourceTree = "<group>"; };
8E10DB952CB709D300862B82 /* BluetoothPeripheral.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothPeripheral.kt; sourceTree = "<group>"; };
8E10DB962CB709D300862B82 /* BluetoothPeripheralManager.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothPeripheralManager.kt; sourceTree = "<group>"; };
8E10DB972CB709D300862B82 /* BluetoothService.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothService.kt; sourceTree = "<group>"; };
8E10DB982CB709D300862B82 /* NSData.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NSData.kt; sourceTree = "<group>"; };
8E10DB992CB709D300862B82 /* PeripheralDelegate.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = PeripheralDelegate.kt; sourceTree = "<group>"; };
8E10DB9E2CB709D300862B82 /* AdvertisementDataRetrievalKeys.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = AdvertisementDataRetrievalKeys.kt; sourceTree = "<group>"; };
8E10DB9F2CB709D300862B82 /* ApplicationContext.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ApplicationContext.kt; sourceTree = "<group>"; };
8E10DBA02CB709D300862B82 /* BlueFalcon.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BlueFalcon.kt; sourceTree = "<group>"; };
8E10DBA12CB709D300862B82 /* BlueFalconDelegate.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BlueFalconDelegate.kt; sourceTree = "<group>"; };
8E10DBA22CB709D300862B82 /* BluetoothCharacteristic.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothCharacteristic.kt; sourceTree = "<group>"; };
8E10DBA32CB709D300862B82 /* BluetoothPeripheral.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothPeripheral.kt; sourceTree = "<group>"; };
8E10DBA42CB709D300862B82 /* BluetoothService.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BluetoothService.kt; sourceTree = "<group>"; };
8E10DBA52CB709D300862B82 /* Exceptions.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Exceptions.kt; sourceTree = "<group>"; };
8E10DBA62CB709D300862B82 /* Log.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Log.kt; sourceTree = "<group>"; };
8E10DBA72CB709D300862B82 /* Logger.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Logger.kt; sourceTree = "<group>"; };
8E10DBA82CB709D300862B82 /* NativeFlow.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NativeFlow.kt; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -59,6 +77,8 @@
7555FF72242A565900829871 = {
isa = PBXGroup;
children = (
8E10DB9D2CB709D300862B82 /* appleMain */,
8E10DBAC2CB709D300862B82 /* commonMain */,
7555FF7D242A565900829871 /* iosBlueFalconExampleMP */,
7555FF7C242A565900829871 /* Products */,
7555FFB0242A642200829871 /* Frameworks */,
Expand Down Expand Up @@ -93,6 +113,88 @@
name = Frameworks;
sourceTree = "<group>";
};
8E10DB9A2CB709D300862B82 /* bluefalcon */ = {
isa = PBXGroup;
children = (
8E10DB932CB709D300862B82 /* BlueFalcon.kt */,
8E10DB942CB709D300862B82 /* BluetoothCharacteristic.kt */,
8E10DB952CB709D300862B82 /* BluetoothPeripheral.kt */,
8E10DB962CB709D300862B82 /* BluetoothPeripheralManager.kt */,
8E10DB972CB709D300862B82 /* BluetoothService.kt */,
8E10DB982CB709D300862B82 /* NSData.kt */,
8E10DB992CB709D300862B82 /* PeripheralDelegate.kt */,
);
path = bluefalcon;
sourceTree = "<group>";
};
8E10DB9B2CB709D300862B82 /* dev */ = {
isa = PBXGroup;
children = (
8E10DB9A2CB709D300862B82 /* bluefalcon */,
);
path = dev;
sourceTree = "<group>";
};
8E10DB9C2CB709D300862B82 /* kotlin */ = {
isa = PBXGroup;
children = (
8E10DB9B2CB709D300862B82 /* dev */,
);
path = kotlin;
sourceTree = "<group>";
};
8E10DB9D2CB709D300862B82 /* appleMain */ = {
isa = PBXGroup;
children = (
8E10DB9C2CB709D300862B82 /* kotlin */,
);
name = appleMain;
path = "/Users/andrew.reed/Documents/workspace/blue-falcon/library/src/appleMain";
sourceTree = "<absolute>";
};
8E10DBA92CB709D300862B82 /* bluefalcon */ = {
isa = PBXGroup;
children = (
8E10DB9E2CB709D300862B82 /* AdvertisementDataRetrievalKeys.kt */,
8E10DB9F2CB709D300862B82 /* ApplicationContext.kt */,
8E10DBA02CB709D300862B82 /* BlueFalcon.kt */,
8E10DBA12CB709D300862B82 /* BlueFalconDelegate.kt */,
8E10DBA22CB709D300862B82 /* BluetoothCharacteristic.kt */,
8E10DBA32CB709D300862B82 /* BluetoothPeripheral.kt */,
8E10DBA42CB709D300862B82 /* BluetoothService.kt */,
8E10DBA52CB709D300862B82 /* Exceptions.kt */,
8E10DBA62CB709D300862B82 /* Log.kt */,
8E10DBA72CB709D300862B82 /* Logger.kt */,
8E10DBA82CB709D300862B82 /* NativeFlow.kt */,
);
path = bluefalcon;
sourceTree = "<group>";
};
8E10DBAA2CB709D300862B82 /* dev */ = {
isa = PBXGroup;
children = (
8E10DBA92CB709D300862B82 /* bluefalcon */,
);
path = dev;
sourceTree = "<group>";
};
8E10DBAB2CB709D300862B82 /* kotlin */ = {
isa = PBXGroup;
children = (
8E10DBAA2CB709D300862B82 /* dev */,
);
path = kotlin;
sourceTree = "<group>";
};
8E10DBAC2CB709D300862B82 /* commonMain */ = {
isa = PBXGroup;
children = (
8E10DBAB2CB709D300862B82 /* kotlin */,
);
name = commonMain;
path = "/Users/andrew.reed/Documents/workspace/blue-falcon/library/src/commonMain";
sourceTree = "<absolute>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -316,7 +418,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"iosBlueFalconExampleMP/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = L2QD36XTFJ;
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -332,7 +434,7 @@
"-framework",
shared,
);
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosBlueFalconCMPExample;
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosBlueFalconCMPExampleA;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -345,7 +447,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"iosBlueFalconExampleMP/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = L2QD36XTFJ;
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -361,7 +463,7 @@
"-framework",
shared,
);
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosBlueFalconCMPExample;
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosBlueFalconCMPExampleA;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This example needs bluetooth usage permission to demonstrate the capabilities of BlueFalcon in this example project.</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand All @@ -46,7 +48,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This example needs bluetooth usage permission to demonstrate the capabilities of BlueFalcon in this example project.</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ kotlin {
implementation("dev.icerock.moko:mvvm-flow-compose:0.16.1")

// BlueFalcon dependency here
implementation("dev.bluefalcon:blue-falcon:1.1.0")
implementation("dev.bluefalcon:blue-falcon:2.0.0")
}
}
val commonTest by getting {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ actual class AppModule(
private val context: Context
) {
actual val blueFalcon: BlueFalcon
get() = BlueFalcon(context as ApplicationContext)
get() = BlueFalcon(
log = null,
context as ApplicationContext,
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.bluefalconcomposemultiplatform.ble.data

import AdvertisementDataRetrievalKeys
import dev.bluefalcon.AdvertisementDataRetrievalKeys
import dev.bluefalcon.BlueFalconDelegate
import dev.bluefalcon.BluetoothCharacteristic
import dev.bluefalcon.BluetoothCharacteristicDescriptor
Expand Down Expand Up @@ -40,13 +40,6 @@ class BleDelegate: BlueFalconDelegate {

}

override fun didDiscoverDevice(
bluetoothPeripheral: BluetoothPeripheral,
advertisementData: Map<AdvertisementDataRetrievalKeys, Any>
) {

}

override fun didDiscoverServices(bluetoothPeripheral: BluetoothPeripheral) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ class BluetoothDeviceViewModel(
blueFalcon.disconnect(it.peripheral)
}
}

is UiEvent.OnReadCharacteristic -> {
_deviceState.value.devices[event.macId]?.let {
blueFalcon.readCharacteristic(it.peripheral, event.characteristic)
}
}
is UiEvent.OnWriteCharacteristic -> {
_deviceState.value.devices[event.macId]?.let {
blueFalcon.writeCharacteristic(it.peripheral, event.characteristic, event.value, null)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.example.bluefalconcomposemultiplatform.ble.presentation

import dev.bluefalcon.BluetoothCharacteristic

sealed interface UiEvent {
object OnScanClick: UiEvent
data class OnConnectClick(val macId: String): UiEvent
data class OnDisconnectClick(val macId: String): UiEvent

data class OnReadCharacteristic(val macId: String, val characteristic: BluetoothCharacteristic): UiEvent
data class OnWriteCharacteristic(val macId: String, val characteristic: BluetoothCharacteristic, val value: String): UiEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ fun DeviceScanView(
.padding(10.dp),
) {
LazyColumn {
items(state.devices.values.toList()) { device ->
items(state.devices.values.toList().sortedByDescending { it.peripheral.name }) { device ->
FoundDeviceCard(
deviceName = if (!device.peripheral.name.isNullOrBlank()) device.peripheral.name else "No Name",
macId = device.peripheral.uuid,
rssi = device.peripheral.rssi,
services = device.peripheral.services.values.toList(),
connected = device.connected,
onEvent = onEvent
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
Expand All @@ -17,12 +18,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.bluefalconcomposemultiplatform.ble.presentation.UiEvent
import dev.bluefalcon.BluetoothCharacteristic
import dev.bluefalcon.BluetoothService

@Composable
fun FoundDeviceCard(
deviceName: String?,
macId: String,
rssi: Float?,
services: List<BluetoothService>,
connected: Boolean,
onEvent: (UiEvent) -> Unit
) {
Expand Down Expand Up @@ -62,7 +66,16 @@ fun FoundDeviceCard(
fontSize = 8.sp
)
}

Column {
Text(
"Services",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 8.sp
)
services.forEach {
ServiceRow(macId, it, onEvent)
}
}
}
if (!connected) {
Button(
Expand All @@ -84,4 +97,66 @@ fun FoundDeviceCard(

}
}
}
}

@Composable
fun ServiceRow(
macId: String,
service: BluetoothService,
onEvent: (UiEvent) -> Unit
) {
Column {
Text(
"Name: ${service.name}",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 6.sp
)
Column {
service.characteristics.forEach {
CharacteristicsRow(macId, it, onEvent)
}
}
}
}

@Composable
fun CharacteristicsRow(
macId: String,
characteristic: BluetoothCharacteristic,
onEvent: (UiEvent) -> Unit
) {
Column {
Text(
"Name: ${characteristic.name}",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 6.sp
)
Text(
"Value: ${characteristic.value.contentToString()}",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 6.sp
)
Row {
Button(
onClick = {
onEvent(UiEvent.OnReadCharacteristic(macId, characteristic))
},
modifier = Modifier
.width(140.dp)
.padding(start = 20.dp, top = 20.dp)
) {
Text("Read")
}
Button(
onClick = {
onEvent(UiEvent.OnWriteCharacteristic(macId, characteristic, "123"))
},
modifier = Modifier
.width(140.dp)
.padding(start = 20.dp, top = 20.dp)
) {
Text("Write")
}
}
}
}
2 changes: 1 addition & 1 deletion examples/KotlinMP-Example/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref =
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" }
blue-falcon = { module = "dev.bluefalcon:blue-falcon", version = "1.1.1" }
blue-falcon = { module = "dev.bluefalcon:blue-falcon", version = "2.0.0" }
kmm-viewmodel = { module = "com.rickclephas.kmp:kmp-observableviewmodel-core", version = "1.0.0-BETA-3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
compose-permissions = { group = "com.github.dawidraszka.compose-permission-handler", name = "core", version = "1.5.0" }
Expand Down
4 changes: 4 additions & 0 deletions examples/KotlinMP-Example/shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ android {
defaultConfig {
minSdk = 24
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
Loading

0 comments on commit 899b954

Please sign in to comment.