Skip to content

Commit 5f322ea

Browse files
committed
Working
1 parent 85b20f9 commit 5f322ea

10 files changed

Lines changed: 163 additions & 19 deletions

File tree

‎ios/Podfile.lock‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,12 @@ PODS:
320320
- react-native-ble-plx (2.0.3):
321321
- MultiplatformBleAdapter (= 0.1.9)
322322
- React-Core
323+
- react-native-safe-area-context (4.4.1):
324+
- RCT-Folly
325+
- RCTRequired
326+
- RCTTypeSafety
327+
- React-Core
328+
- ReactCommon/turbomodule/core
323329
- react-native-skia (0.1.157):
324330
- React
325331
- React-callinvoker
@@ -415,6 +421,9 @@ PODS:
415421
- React-jsi (= 0.70.8)
416422
- React-logger (= 0.70.8)
417423
- React-perflogger (= 0.70.8)
424+
- RNScreens (3.18.2):
425+
- React-Core
426+
- React-RCTImage
418427
- Yoga (1.14.0)
419428

420429
DEPENDENCIES:
@@ -455,6 +464,7 @@ DEPENDENCIES:
455464
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
456465
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
457466
- react-native-ble-plx (from `../node_modules/react-native-ble-plx`)
467+
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
458468
- "react-native-skia (from `../node_modules/@shopify/react-native-skia`)"
459469
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
460470
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
@@ -468,6 +478,7 @@ DEPENDENCIES:
468478
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
469479
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
470480
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
481+
- RNScreens (from `../node_modules/react-native-screens`)
471482
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
472483

473484
SPEC REPOS:
@@ -548,6 +559,8 @@ EXTERNAL SOURCES:
548559
:path: "../node_modules/react-native/ReactCommon/logger"
549560
react-native-ble-plx:
550561
:path: "../node_modules/react-native-ble-plx"
562+
react-native-safe-area-context:
563+
:path: "../node_modules/react-native-safe-area-context"
551564
react-native-skia:
552565
:path: "../node_modules/@shopify/react-native-skia"
553566
React-perflogger:
@@ -574,6 +587,8 @@ EXTERNAL SOURCES:
574587
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
575588
ReactCommon:
576589
:path: "../node_modules/react-native/ReactCommon"
590+
RNScreens:
591+
:path: "../node_modules/react-native-screens"
577592
Yoga:
578593
:path: "../node_modules/react-native/ReactCommon/yoga"
579594

@@ -616,6 +631,7 @@ SPEC CHECKSUMS:
616631
React-jsinspector: 5e5497c844f2381e8648ec3a7d0ad25b3f27f23e
617632
React-logger: b277ad8f4473f2506fb30b762b6348534a3de10e
618633
react-native-ble-plx: f10240444452dfb2d2a13a0e4f58d7783e92d76e
634+
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
619635
react-native-skia: 7f9a3bd36c4247005e87005d912dcf6db76a6289
620636
React-perflogger: e9249a18e055cae96fdf685bf6145cbea62506c8
621637
React-RCTActionSheet: a6d2a544a4605a111ce80fa9319cc870ca3ea778
@@ -629,6 +645,7 @@ SPEC CHECKSUMS:
629645
React-RCTVibration: 19d21a3ed620352180800447771f68a101f196e9
630646
React-runtimeexecutor: f795fd426264709901c09432c6ce072f8400147e
631647
ReactCommon: c440e7f15075e81eb29802521c58a1f38b1aa903
648+
RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d
632649
Yoga: d6133108734e69e8c0becc6ba587294b94829687
633650

634651
PODFILE CHECKSUM: 64065283ea548937528126d1d39d9c91d0fbfcc8

‎ios/expoblesample.xcodeproj/project.pbxproj‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@
170170
TargetAttributes = {
171171
13B07F861A680F5B00A75B9A = {
172172
LastSwiftMigration = 1250;
173+
DevelopmentTeam = "4L58M98Y42";
174+
ProvisioningStyle = Automatic;
173175
};
174176
};
175177
};
@@ -329,6 +331,9 @@
329331
SWIFT_VERSION = 5.0;
330332
TARGETED_DEVICE_FAMILY = "1,2";
331333
VERSIONING_SYSTEM = "apple-generic";
334+
DEVELOPMENT_TEAM = "4L58M98Y42";
335+
CODE_SIGN_IDENTITY = "Apple Development";
336+
CODE_SIGN_STYLE = Automatic;
332337
};
333338
name = Debug;
334339
};
@@ -354,6 +359,9 @@
354359
SWIFT_VERSION = 5.0;
355360
TARGETED_DEVICE_FAMILY = "1,2";
356361
VERSIONING_SYSTEM = "apple-generic";
362+
DEVELOPMENT_TEAM = "4L58M98Y42";
363+
CODE_SIGN_IDENTITY = "Apple Development";
364+
CODE_SIGN_STYLE = Automatic;
357365
};
358366
name = Release;
359367
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

‎src/screens/Connect/Connect.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useAppDispatch, useAppSelector } from "../../state/store";
66
import { connectToDevice } from "../../state/BluetoothLowEnergy/listener";
77
import { DeviceReference } from "../../state/BluetoothLowEnergy/BluetoothLeManager";
88
import { useNavigation } from "@react-navigation/native";
9-
import { FontWeight } from "@shopify/react-native-skia";
109

1110
export const Connect = () => {
1211
const nav = useNavigation();

‎src/screens/Read/Read.tsx‎

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
11
import React from "react";
2-
import { View, Text, StyleSheet } from "react-native";
2+
import { View, Text, StyleSheet, Pressable } from "react-native";
3+
import { useAppDispatch, useAppSelector } from "../../state/store";
4+
import { readColorData } from "../../state/BluetoothLowEnergy/listener";
35

4-
export const Read = () => (
5-
<View style={styles.container}>
6-
<Text>Read</Text>
7-
</View>
8-
);
6+
export const Read = () => {
7+
const dispatch = useAppDispatch();
8+
const backgroundColor = useAppSelector((state) => state.ble.retrievedColor);
9+
console.log("backgroundColor", backgroundColor);
10+
11+
const readRemoteColor = () => {
12+
dispatch(readColorData());
13+
};
14+
15+
return (
16+
<View
17+
style={[
18+
styles.container,
19+
{ backgroundColor: backgroundColor ?? "#FFFFFF" },
20+
]}
21+
>
22+
<Pressable style={styles.button} onPress={readRemoteColor}>
23+
<Text style={styles.ctaBtnTxt}>Read Color From Server</Text>
24+
</Pressable>
25+
</View>
26+
);
27+
};
928

1029
const styles = StyleSheet.create({
1130
container: {
1231
flex: 1,
1332
justifyContent: "center",
1433
alignItems: "center",
1534
},
35+
button: {
36+
backgroundColor: "purple",
37+
paddingVertical: 15,
38+
paddingHorizontal: 20,
39+
borderRadius: 15,
40+
},
41+
ctaBtnTxt: {
42+
fontSize: 20,
43+
color: "white",
44+
fontWeight: "bold",
45+
},
1646
});

‎src/screens/Write/Write.tsx‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11
import React from "react";
2-
import { View, Text, StyleSheet } from "react-native";
2+
import { View, Text, StyleSheet, Pressable } from "react-native";
3+
import { useAppDispatch } from "../../state/store";
4+
import { sendColorData } from "../../state/BluetoothLowEnergy/listener";
35

4-
export const Write = () => (
5-
<View style={styles.container}>
6-
<Text>Write</Text>
7-
</View>
8-
);
6+
export const Write = () => {
7+
const dispatch = useAppDispatch();
8+
const sendData = () => {
9+
const randomColor = Math.floor(Math.random() * 16777215).toString(16);
10+
dispatch(sendColorData(randomColor));
11+
};
12+
13+
return (
14+
<View style={styles.container}>
15+
<Pressable style={styles.button} onPress={sendData}>
16+
<Text style={styles.ctaBtnTxt}>Send Random Color To Server</Text>
17+
</Pressable>
18+
</View>
19+
);
20+
};
921

1022
const styles = StyleSheet.create({
1123
container: {
1224
flex: 1,
1325
justifyContent: "center",
1426
alignItems: "center",
1527
},
28+
button: {
29+
backgroundColor: "purple",
30+
paddingVertical: 15,
31+
paddingHorizontal: 20,
32+
borderRadius: 15,
33+
},
34+
ctaBtnTxt: {
35+
fontSize: 20,
36+
color: "white",
37+
fontWeight: "bold",
38+
},
1639
});

‎src/state/BluetoothLowEnergy/BluetoothLeManager.ts‎

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {
88
} from "react-native-ble-plx";
99

1010
const COLOR_SERVICE = "96e4d99a-066f-444c-b67c-112345e3b1a2";
11-
const COLOR_CHARACTARISTIC = "7c0209c0-93f0-437a-828a-a58379b230c4";
11+
const COLOR_CHARACTARISTIC_NOTIFY = "7c0209c0-93f0-437a-828a-a58379b230c4";
12+
const COLOR_CHARACTARISTIC_WRITE = "1b3dcc2d-cc56-4b47-b6c2-13745858c7df";
13+
const COLOR_CHARACTARISTIC_READ = "3d84e60b-90d0-40d4-993a-1b83424cb868";
1214

1315
export interface DeviceReference {
1416
name?: string | null;
@@ -31,7 +33,7 @@ class BluetoothLeManager {
3133
this.bleManager.startDeviceScan(null, null, (error, scannedDevice) => {
3234
onDeviceFound({
3335
id: scannedDevice?.id,
34-
name: scannedDevice?.name ?? scannedDevice?.localName,
36+
name: scannedDevice?.localName ?? scannedDevice?.name,
3537
});
3638
return;
3739
});
@@ -43,6 +45,7 @@ class BluetoothLeManager {
4345

4446
connectToPeripheral = async (identifier: string) => {
4547
this.device = await this.bleManager.connectToDevice(identifier);
48+
await this.device?.discoverAllServicesAndCharacteristics();
4649
};
4750

4851
onColorUpdate = (
@@ -66,17 +69,43 @@ class BluetoothLeManager {
6669
startStreamingData = async (
6770
emitter: (bleValue: { payload: string | BleError }) => void
6871
) => {
69-
await this.device?.discoverAllServicesAndCharacteristics();
7072
if (!this.isListening) {
7173
this.isListening = true;
7274
this.device?.monitorCharacteristicForService(
7375
COLOR_SERVICE,
74-
COLOR_CHARACTARISTIC,
76+
COLOR_CHARACTARISTIC_NOTIFY,
7577
(error, characteristic) =>
7678
this.onColorUpdate(error, characteristic, emitter)
7779
);
7880
}
7981
};
82+
83+
sendColor = async (color: string) => {
84+
const data = base64.encode(color);
85+
try {
86+
await this.bleManager.writeCharacteristicWithResponseForDevice(
87+
this.device?.id ?? "",
88+
COLOR_SERVICE,
89+
COLOR_CHARACTARISTIC_WRITE,
90+
data
91+
);
92+
} catch (e) {
93+
console.log(e);
94+
}
95+
};
96+
97+
readColor = async () => {
98+
try {
99+
const color = await this.bleManager.readCharacteristicForDevice(
100+
this.device?.id ?? "",
101+
COLOR_SERVICE,
102+
COLOR_CHARACTARISTIC_READ
103+
);
104+
return base64.decode(color.value ?? "");
105+
} catch (e) {
106+
console.log(e);
107+
}
108+
};
80109
}
81110

82111
const bluetoothLeManager = new BluetoothLeManager();

‎src/state/BluetoothLowEnergy/listener.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
setColor,
44
setConnectedDevice,
55
setDevices,
6+
setRetrievedColor,
67
startListeningForColors,
78
startScanning,
89
} from "./slice";
@@ -20,6 +21,22 @@ export const connectToDevice = createAsyncThunk(
2021
}
2122
);
2223

24+
export const sendColorData = createAsyncThunk(
25+
"bleThunk/sendColorData",
26+
async (color: string, thunkApi) => {
27+
await bluetoothLeManager.sendColor(color);
28+
thunkApi.dispatch(setColor(color));
29+
}
30+
);
31+
32+
export const readColorData = createAsyncThunk(
33+
"bleThunk/readColorData",
34+
async (_, thunkApi) => {
35+
const color = await bluetoothLeManager.readColor();
36+
thunkApi.dispatch(setRetrievedColor(color));
37+
}
38+
);
39+
2340
bleMiddleware.startListening({
2441
actionCreator: startScanning,
2542
effect: (_, listenerApi) => {

‎src/state/BluetoothLowEnergy/slice.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ interface BluetoothState {
66
allDevices: DeviceReference[];
77
currentColor: string;
88
connectedDevice: DeviceReference | null;
9+
retrievedColor?: string | null;
910
}
1011

1112
const initialState: BluetoothState = {
1213
allDevices: [],
1314
currentColor: "#FFFFFF",
1415
connectedDevice: null,
16+
retrievedColor: undefined,
1517
};
1618

1719
export type DevicesAction = PayloadAction<DeviceReference>;
@@ -43,9 +45,16 @@ const bleSlice = createSlice({
4345
setConnectedDevice: (state, action: PayloadAction<DeviceReference>) => {
4446
state.connectedDevice = action.payload;
4547
},
48+
setRetrievedColor: (
49+
state,
50+
action: PayloadAction<string | undefined | null>
51+
) => {
52+
state.retrievedColor = action.payload;
53+
},
4654
},
4755
});
4856

49-
export const { setDevices, setColor, setConnectedDevice } = bleSlice.actions;
57+
export const { setDevices, setColor, setConnectedDevice, setRetrievedColor } =
58+
bleSlice.actions;
5059

5160
export default bleSlice.reducer;

‎src/useBLE.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,14 @@ function useBLE(): BluetoothLowEnergyApi {
9292

9393
const scanForPeripherals = () =>
9494
bleManager.startDeviceScan(null, null, (error, device) => {
95+
console.log("device", device?.name);
9596
if (error) {
9697
console.log(error);
9798
}
98-
if (device && device.name?.includes("BLESIM")) {
99+
if (
100+
(device && device.name?.includes("BLESIM")) ||
101+
device?.localName?.includes("BLESIM")
102+
) {
99103
setAllDevices((prevState: Device[]) => {
100104
if (!isDuplicteDevice(prevState, device)) {
101105
return [...prevState, device];

0 commit comments

Comments
 (0)