react-native-ble-manager 10.1.4 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/android/src/main/java/it/innove/BleManager.java +5 -5
- package/android/src/main/java/it/innove/DefaultPeripheral.java +10 -5
- package/android/src/main/java/it/innove/DefaultScanManager.java +8 -5
- package/android/src/main/java/it/innove/Peripheral.java +21 -17
- package/dist/cjs/index.js +8 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.d.ts +3 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/index.js +8 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.d.ts +3 -2
- package/dist/esm/types.js.map +1 -1
- package/ios/BleManager-Bridging-Header.h +1 -0
- package/ios/BleManager.h +0 -28
- package/ios/BleManager.m +126 -1186
- package/ios/BleManager.swift +1185 -0
- package/ios/BleManager.xcodeproj/project.pbxproj +21 -18
- package/ios/BleManager.xcodeproj/project.xcworkspace/xcuserdata/marco.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Helper.swift +364 -0
- package/package.json +1 -1
- package/react-native-ble-manager.podspec +2 -2
- package/src/index.ts +7 -3
- package/src/types.ts +3 -2
- package/ios/BLECommandContext.h +0 -10
- package/ios/BLECommandContext.m +0 -5
- package/ios/CBPeripheral+Extensions.h +0 -16
- package/ios/CBPeripheral+Extensions.m +0 -309
- package/ios/NSData+Conversion.h +0 -11
- package/ios/NSData+Conversion.m +0 -41
|
@@ -7,10 +7,9 @@
|
|
|
7
7
|
objects = {
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
|
-
A908F1921CEEFEB500BE1488 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = A908F18B1CEEFEB500BE1488 /* NSData+Conversion.m */; };
|
|
11
|
-
A908F1931CEEFEB500BE1488 /* CBPeripheral+Extensions.m in Sources */ = {isa = PBXBuildFile; fileRef = A908F18D1CEEFEB500BE1488 /* CBPeripheral+Extensions.m */; };
|
|
12
|
-
A908F1941CEEFEB500BE1488 /* BLECommandContext.m in Sources */ = {isa = PBXBuildFile; fileRef = A908F18F1CEEFEB500BE1488 /* BLECommandContext.m */; };
|
|
13
10
|
A908F1951CEEFEB500BE1488 /* BleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A908F1911CEEFEB500BE1488 /* BleManager.m */; };
|
|
11
|
+
A918B6872B15F605006EC956 /* BleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A918B6862B15F605006EC956 /* BleManager.swift */; };
|
|
12
|
+
A918B68D2B162CF2006EC956 /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A918B68C2B162CF2006EC956 /* Helper.swift */; };
|
|
14
13
|
/* End PBXBuildFile section */
|
|
15
14
|
|
|
16
15
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -27,14 +26,11 @@
|
|
|
27
26
|
|
|
28
27
|
/* Begin PBXFileReference section */
|
|
29
28
|
134814201AA4EA6300B7C361 /* libBleManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBleManager.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
30
|
-
A908F18A1CEEFEB500BE1488 /* NSData+Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Conversion.h"; sourceTree = "<group>"; };
|
|
31
|
-
A908F18B1CEEFEB500BE1488 /* NSData+Conversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Conversion.m"; sourceTree = "<group>"; };
|
|
32
|
-
A908F18C1CEEFEB500BE1488 /* CBPeripheral+Extensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CBPeripheral+Extensions.h"; sourceTree = "<group>"; };
|
|
33
|
-
A908F18D1CEEFEB500BE1488 /* CBPeripheral+Extensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CBPeripheral+Extensions.m"; sourceTree = "<group>"; };
|
|
34
|
-
A908F18E1CEEFEB500BE1488 /* BLECommandContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BLECommandContext.h; sourceTree = "<group>"; };
|
|
35
|
-
A908F18F1CEEFEB500BE1488 /* BLECommandContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BLECommandContext.m; sourceTree = "<group>"; };
|
|
36
29
|
A908F1901CEEFEB500BE1488 /* BleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BleManager.h; sourceTree = "<group>"; };
|
|
37
30
|
A908F1911CEEFEB500BE1488 /* BleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BleManager.m; sourceTree = "<group>"; };
|
|
31
|
+
A918B6852B15F605006EC956 /* BleManager-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BleManager-Bridging-Header.h"; sourceTree = "<group>"; };
|
|
32
|
+
A918B6862B15F605006EC956 /* BleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BleManager.swift; sourceTree = "<group>"; };
|
|
33
|
+
A918B68C2B162CF2006EC956 /* Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = "<group>"; };
|
|
38
34
|
/* End PBXFileReference section */
|
|
39
35
|
|
|
40
36
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -67,14 +63,11 @@
|
|
|
67
63
|
A908F1891CEEFE0F00BE1488 /* BleManager */ = {
|
|
68
64
|
isa = PBXGroup;
|
|
69
65
|
children = (
|
|
70
|
-
|
|
71
|
-
A908F18B1CEEFEB500BE1488 /* NSData+Conversion.m */,
|
|
72
|
-
A908F18C1CEEFEB500BE1488 /* CBPeripheral+Extensions.h */,
|
|
73
|
-
A908F18D1CEEFEB500BE1488 /* CBPeripheral+Extensions.m */,
|
|
74
|
-
A908F18E1CEEFEB500BE1488 /* BLECommandContext.h */,
|
|
75
|
-
A908F18F1CEEFEB500BE1488 /* BLECommandContext.m */,
|
|
66
|
+
A918B68C2B162CF2006EC956 /* Helper.swift */,
|
|
76
67
|
A908F1901CEEFEB500BE1488 /* BleManager.h */,
|
|
77
68
|
A908F1911CEEFEB500BE1488 /* BleManager.m */,
|
|
69
|
+
A918B6862B15F605006EC956 /* BleManager.swift */,
|
|
70
|
+
A918B6852B15F605006EC956 /* BleManager-Bridging-Header.h */,
|
|
78
71
|
);
|
|
79
72
|
name = BleManager;
|
|
80
73
|
sourceTree = "<group>";
|
|
@@ -110,6 +103,7 @@
|
|
|
110
103
|
TargetAttributes = {
|
|
111
104
|
58B511DA1A9E6C8500147676 = {
|
|
112
105
|
CreatedOnToolsVersion = 6.1.1;
|
|
106
|
+
LastSwiftMigration = 1500;
|
|
113
107
|
};
|
|
114
108
|
};
|
|
115
109
|
};
|
|
@@ -118,6 +112,7 @@
|
|
|
118
112
|
developmentRegion = English;
|
|
119
113
|
hasScannedForEncodings = 0;
|
|
120
114
|
knownRegions = (
|
|
115
|
+
English,
|
|
121
116
|
en,
|
|
122
117
|
);
|
|
123
118
|
mainGroup = 58B511D21A9E6C8500147676;
|
|
@@ -135,10 +130,9 @@
|
|
|
135
130
|
isa = PBXSourcesBuildPhase;
|
|
136
131
|
buildActionMask = 2147483647;
|
|
137
132
|
files = (
|
|
138
|
-
A908F1931CEEFEB500BE1488 /* CBPeripheral+Extensions.m in Sources */,
|
|
139
133
|
A908F1951CEEFEB500BE1488 /* BleManager.m in Sources */,
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
A918B6872B15F605006EC956 /* BleManager.swift in Sources */,
|
|
135
|
+
A918B68D2B162CF2006EC956 /* Helper.swift in Sources */,
|
|
142
136
|
);
|
|
143
137
|
runOnlyForDeploymentPostprocessing = 0;
|
|
144
138
|
};
|
|
@@ -255,6 +249,7 @@
|
|
|
255
249
|
58B511F01A9E6C8500147676 /* Debug */ = {
|
|
256
250
|
isa = XCBuildConfiguration;
|
|
257
251
|
buildSettings = {
|
|
252
|
+
CLANG_ENABLE_MODULES = YES;
|
|
258
253
|
HEADER_SEARCH_PATHS = (
|
|
259
254
|
"$(inherited)",
|
|
260
255
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
@@ -265,17 +260,22 @@
|
|
|
265
260
|
"$(SRCROOT)/node_modules/react-native/React/**",
|
|
266
261
|
"$(SRCROOT)/../../../ios/Pods/Headers/Public/**",
|
|
267
262
|
);
|
|
263
|
+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
|
268
264
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
269
265
|
OTHER_LDFLAGS = "-ObjC";
|
|
270
266
|
PRODUCT_NAME = BleManager;
|
|
271
267
|
SDKROOT = iphoneos;
|
|
272
268
|
SKIP_INSTALL = YES;
|
|
269
|
+
SWIFT_OBJC_BRIDGING_HEADER = "BleManager-Bridging-Header.h";
|
|
270
|
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
271
|
+
SWIFT_VERSION = 5.0;
|
|
273
272
|
};
|
|
274
273
|
name = Debug;
|
|
275
274
|
};
|
|
276
275
|
58B511F11A9E6C8500147676 /* Release */ = {
|
|
277
276
|
isa = XCBuildConfiguration;
|
|
278
277
|
buildSettings = {
|
|
278
|
+
CLANG_ENABLE_MODULES = YES;
|
|
279
279
|
HEADER_SEARCH_PATHS = (
|
|
280
280
|
"$(inherited)",
|
|
281
281
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
@@ -286,11 +286,14 @@
|
|
|
286
286
|
"$(SRCROOT)/node_modules/react-native/React/**",
|
|
287
287
|
"$(SRCROOT)/../../../ios/Pods/Headers/Public/**",
|
|
288
288
|
);
|
|
289
|
+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
|
289
290
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
290
291
|
OTHER_LDFLAGS = "-ObjC";
|
|
291
292
|
PRODUCT_NAME = BleManager;
|
|
292
293
|
SDKROOT = iphoneos;
|
|
293
294
|
SKIP_INSTALL = YES;
|
|
295
|
+
SWIFT_OBJC_BRIDGING_HEADER = "BleManager-Bridging-Header.h";
|
|
296
|
+
SWIFT_VERSION = 5.0;
|
|
294
297
|
};
|
|
295
298
|
name = Release;
|
|
296
299
|
};
|
|
Binary file
|
package/ios/Helper.swift
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
class Helper {
|
|
4
|
+
static func centralManagerStateToString(_ state: CBManagerState) -> String {
|
|
5
|
+
switch state {
|
|
6
|
+
case .unknown:
|
|
7
|
+
return "unknown"
|
|
8
|
+
case .resetting:
|
|
9
|
+
return "resetting"
|
|
10
|
+
case .unsupported:
|
|
11
|
+
return "unsupported"
|
|
12
|
+
case .unauthorized:
|
|
13
|
+
return "unauthorized"
|
|
14
|
+
case .poweredOff:
|
|
15
|
+
return "poweredOff"
|
|
16
|
+
case .poweredOn:
|
|
17
|
+
return "poweredOn"
|
|
18
|
+
@unknown default:
|
|
19
|
+
return "unknown"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static func dataToArrayBuffer(_ data: Data) -> [String: Any] {
|
|
24
|
+
return [
|
|
25
|
+
"CDVType": "ArrayBuffer",
|
|
26
|
+
"data": data.base64EncodedString(options: []),
|
|
27
|
+
"bytes": data.map { $0 }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static func reformatAdvertisementData(_ advertisementData: [String:Any]) -> [String:Any] {
|
|
32
|
+
var adv = advertisementData
|
|
33
|
+
// Rename 'local name' key
|
|
34
|
+
if let localName = adv[CBAdvertisementDataLocalNameKey] {
|
|
35
|
+
adv.removeValue(forKey: CBAdvertisementDataLocalNameKey)
|
|
36
|
+
adv["localName"] = localName
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Rename 'isConnectable' key
|
|
40
|
+
if let isConnectable = adv[CBAdvertisementDataIsConnectable] {
|
|
41
|
+
adv.removeValue(forKey: CBAdvertisementDataIsConnectable)
|
|
42
|
+
adv["isConnectable"] = isConnectable
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Rename 'power level' key
|
|
46
|
+
if let powerLevel = adv[CBAdvertisementDataTxPowerLevelKey] {
|
|
47
|
+
adv.removeValue(forKey: CBAdvertisementDataTxPowerLevelKey)
|
|
48
|
+
adv["txPowerLevel"] = powerLevel
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Service Data is a dictionary of CBUUID and NSData
|
|
52
|
+
// Convert to String keys with Array Buffer values
|
|
53
|
+
if let serviceData = adv[CBAdvertisementDataServiceDataKey] as? NSMutableDictionary {
|
|
54
|
+
for (key, value) in serviceData {
|
|
55
|
+
if let uuidKey = key as? CBUUID, let dataValue = value as? Data {
|
|
56
|
+
serviceData.removeObject(forKey: uuidKey)
|
|
57
|
+
serviceData[uuidKey.uuidString.lowercased()] = Helper.dataToArrayBuffer(dataValue)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
adv.removeValue(forKey: CBAdvertisementDataServiceDataKey)
|
|
62
|
+
adv["serviceData"] = serviceData
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create a new list of Service UUIDs as Strings instead of CBUUIDs
|
|
66
|
+
if let serviceUUIDs = adv[CBAdvertisementDataServiceUUIDsKey] as? NSMutableArray {
|
|
67
|
+
var serviceUUIDStrings:Array<String> = []
|
|
68
|
+
for value in serviceUUIDs {
|
|
69
|
+
if let uuid = value as? CBUUID {
|
|
70
|
+
serviceUUIDStrings.append(uuid.uuidString.lowercased())
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
adv.removeValue(forKey: CBAdvertisementDataServiceUUIDsKey)
|
|
75
|
+
adv["serviceUUIDs"] = serviceUUIDStrings
|
|
76
|
+
}
|
|
77
|
+
// Solicited Services UUIDs is an array of CBUUIDs, convert into Strings
|
|
78
|
+
if let solicitiedServiceUUIDs = adv[CBAdvertisementDataSolicitedServiceUUIDsKey] as? NSMutableArray {
|
|
79
|
+
var solicitiedServiceUUIDStrings:Array<String> = []
|
|
80
|
+
for value in solicitiedServiceUUIDs {
|
|
81
|
+
if let uuid = value as? CBUUID {
|
|
82
|
+
solicitiedServiceUUIDStrings.append(uuid.uuidString.lowercased())
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
adv.removeValue(forKey: CBAdvertisementDataSolicitedServiceUUIDsKey)
|
|
87
|
+
adv["solicitedServiceUUIDs"] = solicitiedServiceUUIDStrings
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Overflow Services UUIDs is an array of CBUUIDs, convert into Strings
|
|
91
|
+
if let overflowServiceUUIDs = adv[CBAdvertisementDataOverflowServiceUUIDsKey] as? NSMutableArray {
|
|
92
|
+
var overflowServiceUUIDStrings:Array<String> = []
|
|
93
|
+
for value in overflowServiceUUIDs {
|
|
94
|
+
if let uuid = value as? CBUUID {
|
|
95
|
+
overflowServiceUUIDStrings.append(uuid.uuidString.lowercased())
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
adv.removeValue(forKey: CBAdvertisementDataOverflowServiceUUIDsKey)
|
|
100
|
+
adv["overflowServiceUUIDs"] = overflowServiceUUIDStrings
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Convert the manufacturer data
|
|
104
|
+
if let mfgData = adv[CBAdvertisementDataManufacturerDataKey] as? Data {
|
|
105
|
+
if mfgData.count > 1 {
|
|
106
|
+
let manufactureID = UInt16(mfgData[0]) + UInt16(mfgData[1]) << 8
|
|
107
|
+
var manInfo: [String: Any] = [:]
|
|
108
|
+
manInfo[String(format: "%04X", manufactureID)] = mfgData.subdata(in: 2..<mfgData.endIndex)
|
|
109
|
+
adv["manufacturerData"] = mfgData
|
|
110
|
+
}
|
|
111
|
+
adv.removeValue(forKey: CBAdvertisementDataManufacturerDataKey)
|
|
112
|
+
adv["manufacturerRawData"] = mfgData
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return adv
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static func decodeCharacteristicProperties(_ p: CBCharacteristicProperties) -> Dictionary<String, Any> {
|
|
120
|
+
var props: [String: Any] = [:]
|
|
121
|
+
|
|
122
|
+
// NOTE: props strings need to be consistent across iOS and Android
|
|
123
|
+
if p.contains(.broadcast) {
|
|
124
|
+
props["Broadcast"] = "Broadcast"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if p.contains(.read) {
|
|
128
|
+
props["Read"] = "Read"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if p.contains(.writeWithoutResponse) {
|
|
132
|
+
props["WriteWithoutResponse"] = "WriteWithoutResponse"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if p.contains(.write) {
|
|
136
|
+
props["Write"] = "Write"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if p.contains(.notify) {
|
|
140
|
+
props["Notify"] = "Notify"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if p.contains(.indicate) {
|
|
144
|
+
props["Indicate"] = "Indicate"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if p.contains(.authenticatedSignedWrites) {
|
|
148
|
+
props["AuthenticateSignedWrites"] = "AuthenticateSignedWrites"
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if p.contains(.extendedProperties) {
|
|
152
|
+
props["ExtendedProperties"] = "ExtendedProperties"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if p.contains(.notifyEncryptionRequired) {
|
|
156
|
+
props["NotifyEncryptionRequired"] = "NotifyEncryptionRequired"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if p.contains(.indicateEncryptionRequired) {
|
|
160
|
+
props["IndicateEncryptionRequired"] = "IndicateEncryptionRequired"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return props
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static func key(forPeripheral peripheral: CBPeripheral,
|
|
167
|
+
andCharacteristic characteristic: CBCharacteristic) -> String {
|
|
168
|
+
return "\(String(describing: peripheral.uuidAsString))|\(characteristic.uuid)"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static func key(forPeripheral peripheral: CBPeripheral,
|
|
172
|
+
andCharacteristic characteristic: CBCharacteristic,
|
|
173
|
+
andDescriptor descriptor: CBDescriptor) -> String {
|
|
174
|
+
return "\(String(describing: peripheral.uuidAsString))|\(characteristic.uuid)|\(descriptor.uuid)"
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static func findDescriptor(fromUUID UUID: CBUUID, characteristic: CBCharacteristic) -> CBDescriptor? {
|
|
178
|
+
if BleManager.verboseLogging {
|
|
179
|
+
NSLog("Looking for descriptor \(UUID) on characteristic \(characteristic.uuid)")
|
|
180
|
+
}
|
|
181
|
+
for descriptor in characteristic.descriptors ?? [] {
|
|
182
|
+
if descriptor.uuid.isEqual(UUID) {
|
|
183
|
+
if BleManager.verboseLogging {
|
|
184
|
+
NSLog("Found descriptor \(UUID)")
|
|
185
|
+
}
|
|
186
|
+
return descriptor
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return nil // Descriptor not found on this characteristic
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Find a service in a peripheral
|
|
193
|
+
static func findService(fromUUID UUID: CBUUID, peripheral p: CBPeripheral) -> CBService? {
|
|
194
|
+
for service in p.services ?? [] {
|
|
195
|
+
if compareCBUUID(service.uuid, UUID2: UUID) {
|
|
196
|
+
return service
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return nil // Service not found on this peripheral
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static func compareCBUUID(_ UUID1: CBUUID, UUID2: CBUUID) -> Bool {
|
|
204
|
+
return UUID1.uuidString.caseInsensitiveCompare(UUID2.uuidString) == .orderedSame
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Find a characteristic in service with a specific property
|
|
208
|
+
static func findCharacteristic(fromUUID UUID: CBUUID, service: CBService, prop: CBCharacteristicProperties) -> CBCharacteristic? {
|
|
209
|
+
if BleManager.verboseLogging {
|
|
210
|
+
NSLog("Looking for \(UUID) with properties \(prop.rawValue)")
|
|
211
|
+
}
|
|
212
|
+
for characteristic in service.characteristics ?? [] {
|
|
213
|
+
if (characteristic.properties.contains(prop) && characteristic.uuid.isEqual(UUID)) {
|
|
214
|
+
if BleManager.verboseLogging {
|
|
215
|
+
NSLog("Found \(UUID)")
|
|
216
|
+
}
|
|
217
|
+
return characteristic
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return nil // Characteristic with prop not found on this service
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Find a characteristic in service by UUID
|
|
224
|
+
static func findCharacteristic(fromUUID UUID: CBUUID, service: CBService) -> CBCharacteristic? {
|
|
225
|
+
if BleManager.verboseLogging {
|
|
226
|
+
NSLog("Looking for \(UUID)")
|
|
227
|
+
}
|
|
228
|
+
for characteristic in service.characteristics ?? [] {
|
|
229
|
+
if characteristic.uuid.isEqual(UUID) {
|
|
230
|
+
if BleManager.verboseLogging {
|
|
231
|
+
NSLog("Found \(UUID)")
|
|
232
|
+
}
|
|
233
|
+
return characteristic
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return nil // Characteristic not found on this service
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
class Peripheral:Hashable {
|
|
243
|
+
var instance: CBPeripheral
|
|
244
|
+
var rssi: NSNumber?
|
|
245
|
+
var advertisementData: [String:Any]?
|
|
246
|
+
|
|
247
|
+
init(peripheral: CBPeripheral, rssi: NSNumber? = nil, advertisementData: [String:Any]? = nil) {
|
|
248
|
+
self.instance = peripheral
|
|
249
|
+
self.rssi = rssi
|
|
250
|
+
self.advertisementData = advertisementData
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
func setRSSI(_ newRSSI: NSNumber?) {
|
|
254
|
+
self.rssi = newRSSI
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
func setAdvertisementData(_ advertisementData: [String:Any]) {
|
|
258
|
+
self.advertisementData = advertisementData
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
func advertisingInfo() -> Dictionary<String, Any> {
|
|
262
|
+
var peripheralInfo: [String: Any] = [:]
|
|
263
|
+
|
|
264
|
+
peripheralInfo["name"] = instance.name
|
|
265
|
+
peripheralInfo["id"] = instance.uuidAsString()
|
|
266
|
+
peripheralInfo["rssi"] = self.rssi
|
|
267
|
+
if let adv = self.advertisementData {
|
|
268
|
+
peripheralInfo["advertising"] = Helper.reformatAdvertisementData(adv)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return peripheralInfo
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
func servicesInfo() -> Dictionary<String, Any> {
|
|
275
|
+
var servicesInfo: [String: Any] = [:]
|
|
276
|
+
|
|
277
|
+
var serviceList = [[String: Any]]()
|
|
278
|
+
var characteristicList = [[String: Any]]()
|
|
279
|
+
|
|
280
|
+
for service in instance.services ?? [] {
|
|
281
|
+
var serviceDictionary = [String: Any]()
|
|
282
|
+
serviceDictionary["uuid"] = service.uuid.uuidString.lowercased()
|
|
283
|
+
serviceList.append(serviceDictionary)
|
|
284
|
+
|
|
285
|
+
for characteristic in service.characteristics ?? [] {
|
|
286
|
+
var characteristicDictionary = [String: Any]()
|
|
287
|
+
characteristicDictionary["service"] = service.uuid.uuidString.lowercased()
|
|
288
|
+
characteristicDictionary["characteristic"] = characteristic.uuid.uuidString.lowercased()
|
|
289
|
+
|
|
290
|
+
if let value = characteristic.value, value.count > 0 {
|
|
291
|
+
characteristicDictionary["value"] = Helper.dataToArrayBuffer(value)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
characteristicDictionary["properties"] = Helper.decodeCharacteristicProperties(characteristic.properties)
|
|
295
|
+
|
|
296
|
+
characteristicDictionary["isNotifying"] = characteristic.isNotifying
|
|
297
|
+
|
|
298
|
+
var descriptorList = [[String: Any]]()
|
|
299
|
+
for descriptor in characteristic.descriptors ?? [] {
|
|
300
|
+
var descriptorDictionary = [String: Any]()
|
|
301
|
+
descriptorDictionary["uuid"] = descriptor.uuid.uuidString.lowercased()
|
|
302
|
+
|
|
303
|
+
if let value = descriptor.value {
|
|
304
|
+
descriptorDictionary["value"] = value
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
descriptorList.append(descriptorDictionary)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if descriptorList.count > 0 {
|
|
311
|
+
characteristicDictionary["descriptors"] = descriptorList
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
characteristicList.append(characteristicDictionary)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
servicesInfo["services"] = serviceList
|
|
319
|
+
servicesInfo["characteristics"] = characteristicList
|
|
320
|
+
|
|
321
|
+
return servicesInfo
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
static func == (lhs: Peripheral, rhs: Peripheral) -> Bool {
|
|
326
|
+
return lhs.instance.uuidAsString() == rhs.instance.uuidAsString()
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
func hash(into hasher: inout Hasher) {
|
|
330
|
+
hasher.combine(instance.uuidAsString())
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
class BLECommandContext:NSObject {
|
|
335
|
+
var peripheral: Peripheral?
|
|
336
|
+
var service: CBService?
|
|
337
|
+
var characteristic: CBCharacteristic?
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
extension Data {
|
|
341
|
+
func hexadecimalString() -> String {
|
|
342
|
+
/* Returns hexadecimal string of Data. Empty string if data is empty. */
|
|
343
|
+
return map { String(format: "%02hhx", $0) }.joined()
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
func toArray() -> [NSNumber] {
|
|
347
|
+
/* Returns an array of NSNumber representing the hexadecimal values of the bytes in the data. Empty array if data is empty. */
|
|
348
|
+
|
|
349
|
+
let dataBuffer = [UInt8](self)
|
|
350
|
+
|
|
351
|
+
if dataBuffer.isEmpty {
|
|
352
|
+
return []
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return dataBuffer.map { NSNumber(value: $0) }
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
extension CBPeripheral {
|
|
360
|
+
|
|
361
|
+
func uuidAsString() -> String {
|
|
362
|
+
return self.identifier.uuidString.lowercased()
|
|
363
|
+
}
|
|
364
|
+
}
|
package/package.json
CHANGED
|
@@ -9,9 +9,9 @@ Pod::Spec.new do |s|
|
|
|
9
9
|
s.authors = { "Innove" => "https://github.com/innoveit" }
|
|
10
10
|
s.homepage = "https://github.com/innoveit/react-native-ble-manager"
|
|
11
11
|
s.license = "Apache-2.0"
|
|
12
|
-
s.platform = :ios, "
|
|
12
|
+
s.platform = :ios, "9.0"
|
|
13
13
|
s.source = { :git => "https://github.com/innoveit/react-native-ble-manager.git" }
|
|
14
|
-
s.source_files
|
|
14
|
+
s.source_files = "ios/**/*.{h,c,cc,cpp,m,mm,swift}"
|
|
15
15
|
|
|
16
16
|
s.dependency 'React-Core'
|
|
17
17
|
end
|
package/src/index.ts
CHANGED
|
@@ -405,11 +405,15 @@ class BleManager {
|
|
|
405
405
|
scanningOptions.reportDelay = 0;
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
//
|
|
408
|
+
// In Android ScanFilter used to restrict search to devices with a specific advertising name.
|
|
409
409
|
// https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder#setDeviceName(java.lang.String)
|
|
410
|
-
|
|
411
|
-
|
|
410
|
+
// In iOS, this is a whole word match, not a partial search.
|
|
411
|
+
if (!scanningOptions.exactAdvertisingName) {
|
|
412
412
|
delete scanningOptions.exactAdvertisingName;
|
|
413
|
+
} else {
|
|
414
|
+
if (typeof scanningOptions.exactAdvertisingName === 'string') {
|
|
415
|
+
scanningOptions.exactAdvertisingName = [scanningOptions.exactAdvertisingName];
|
|
416
|
+
}
|
|
413
417
|
}
|
|
414
418
|
|
|
415
419
|
bleManager.scan(
|
package/src/types.ts
CHANGED
|
@@ -38,7 +38,8 @@ export interface Peripheral {
|
|
|
38
38
|
export interface AdvertisingData {
|
|
39
39
|
isConnectable?: boolean;
|
|
40
40
|
localName?: string;
|
|
41
|
-
|
|
41
|
+
rawData?: CustomAdvertisingData;
|
|
42
|
+
manufacturerData?: Record<string, CustomAdvertisingData>;
|
|
42
43
|
serviceData?: Record<string, CustomAdvertisingData>;
|
|
43
44
|
serviceUUIDs?: string[];
|
|
44
45
|
txPowerLevel?: number;
|
|
@@ -136,7 +137,7 @@ export interface ScanOptions {
|
|
|
136
137
|
* if `callbackType` is set to `FirstMatch`, the shortenedLocalName will be used for filtering.
|
|
137
138
|
* https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder#setDeviceName(java.lang.String)
|
|
138
139
|
*/
|
|
139
|
-
exactAdvertisingName?: string;
|
|
140
|
+
exactAdvertisingName?: string|string[];
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
/**
|
package/ios/BLECommandContext.h
DELETED
package/ios/BLECommandContext.m
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
#import <objc/runtime.h>
|
|
2
|
-
#import <Foundation/Foundation.h>
|
|
3
|
-
#import <CoreBluetooth/CoreBluetooth.h>
|
|
4
|
-
#import "CBPeripheral+Extensions.h"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@interface CBPeripheral(com_megster_ble_extension)
|
|
8
|
-
|
|
9
|
-
@property (nonatomic, retain) NSDictionary *advertising;
|
|
10
|
-
@property (nonatomic, retain) NSNumber *advertisementRSSI;
|
|
11
|
-
|
|
12
|
-
-(void)setAdvertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber*)rssi;
|
|
13
|
-
-(NSDictionary *)asDictionary;
|
|
14
|
-
-(NSString *)uuidAsString;
|
|
15
|
-
|
|
16
|
-
@end
|