Skip to content

Commit 2d42a73

Browse files
authored
Merge pull request #33 from StarryInternet/capture-only-needed-values
Only capture the absolute necessary values inside closures, to avoid improperly caching or reusing of core bluetooth objects
2 parents eaadfdb + a705e94 commit 2d42a73

2 files changed

Lines changed: 41 additions & 41 deletions

File tree

Sources/CombineCoreBluetooth/CentralManager/Interface+CentralManager.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,24 @@ public struct CentralManager: Sendable {
8383
}
8484

8585
public func connect(_ peripheral: Peripheral, options: PeripheralConnectionOptions? = nil) -> AnyPublisher<Peripheral, Error> {
86-
Publishers.Merge(
87-
didConnectPeripheral
88-
.filter { $0 == peripheral }
89-
.setFailureType(to: Error.self),
90-
didFailToConnectPeripheral
91-
.filter { p, _ in p == peripheral }
92-
.tryMap { _, error in
93-
throw error ?? CentralManagerError.unknownConnectionFailure
94-
}
95-
)
96-
.prefix(1)
97-
.handleEvents(receiveSubscription: { _ in
98-
_connectToPeripheral(peripheral, options)
99-
}, receiveCancel: {
100-
_cancelPeripheralConnection(peripheral)
101-
})
102-
.shareCurrentValue()
103-
.eraseToAnyPublisher()
86+
Publishers.Merge(
87+
didConnectPeripheral
88+
.filter { [id = peripheral.id] p in p.id == id }
89+
.setFailureType(to: Error.self),
90+
didFailToConnectPeripheral
91+
.filter { [id = peripheral.id] p, _ in p.id == id }
92+
.tryMap { _, error in
93+
throw error ?? CentralManagerError.unknownConnectionFailure
94+
}
95+
)
96+
.prefix(1)
97+
.handleEvents(receiveSubscription: { _ in
98+
_connectToPeripheral(peripheral, options)
99+
}, receiveCancel: {
100+
_cancelPeripheralConnection(peripheral)
101+
})
102+
.shareCurrentValue()
103+
.eraseToAnyPublisher()
104104
}
105105

106106
public func cancelPeripheralConnection(_ peripheral: Peripheral) {
@@ -117,10 +117,10 @@ public struct CentralManager: Sendable {
117117
public func monitorConnection(for peripheral: Peripheral) -> AnyPublisher<Bool, Never> {
118118
Publishers.Merge(
119119
didConnectPeripheral
120-
.filter { p in p == peripheral }
120+
.filter { [id = peripheral.id] p in p.id == id }
121121
.map { _ in true },
122122
didDisconnectPeripheral
123-
.filter { (p, error) in p == peripheral }
123+
.filter { [id = peripheral.id] p, _ in p.id == id }
124124
.map { _ in false }
125125
)
126126
.eraseToAnyPublisher()

Sources/CombineCoreBluetooth/Peripheral/Interface+Peripheral.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -190,20 +190,20 @@ public struct Peripheral: Sendable {
190190

191191
private func writeValueWithResponse(_ value: Data, for characteristic: CBCharacteristic) -> AnyPublisher<Void, Error> {
192192
didWriteValueForCharacteristic
193-
.filterFirstValueOrThrow(where: {
194-
$0.uuid == characteristic.uuid
195-
})
196-
.map { _ in }
197-
.handleEvents(receiveSubscription: { [_writeValueForCharacteristic] _ in
198-
_writeValueForCharacteristic(value, characteristic, .withResponse)
199-
})
200-
.shareCurrentValue()
193+
.filterFirstValueOrThrow(where: { [uuid = characteristic.uuid] in
194+
$0.uuid == uuid
195+
})
196+
.map { _ in }
197+
.handleEvents(receiveSubscription: { [_writeValueForCharacteristic] _ in
198+
_writeValueForCharacteristic(value, characteristic, .withResponse)
199+
})
200+
.shareCurrentValue()
201201
}
202202

203203
public func setNotifyValue(_ enabled: Bool, for characteristic: CBCharacteristic) -> AnyPublisher<Void, Error> {
204204
didUpdateNotificationState
205-
.filterFirstValueOrThrow(where: {
206-
$0.uuid == characteristic.uuid
205+
.filterFirstValueOrThrow(where: { [uuid = characteristic.uuid] in
206+
$0.uuid == uuid
207207
})
208208
.map { _ in }
209209
.handleEvents(receiveSubscription: { [_setNotifyValue] _ in
@@ -214,8 +214,8 @@ public struct Peripheral: Sendable {
214214

215215
public func discoverDescriptors(for characteristic: CBCharacteristic) -> AnyPublisher<[CBDescriptor]?, Error> {
216216
didDiscoverDescriptorsForCharacteristic
217-
.filterFirstValueOrThrow(where: {
218-
$0.uuid == characteristic.uuid
217+
.filterFirstValueOrThrow(where: { [uuid = characteristic.uuid] in
218+
$0.uuid == uuid
219219
})
220220
.map(\.descriptors)
221221
.handleEvents(receiveSubscription: { [_discoverDescriptors] _ in
@@ -226,8 +226,8 @@ public struct Peripheral: Sendable {
226226

227227
public func readValue(for descriptor: CBDescriptor) -> AnyPublisher<Any?, Error> {
228228
didUpdateValueForDescriptor
229-
.filterFirstValueOrThrow(where: {
230-
$0.uuid == descriptor.uuid
229+
.filterFirstValueOrThrow(where: { [uuid = descriptor.uuid] in
230+
$0.uuid == uuid
231231
})
232232
.map(\.value)
233233
.handleEvents(receiveSubscription: { [_readValueForDescriptor] _ in
@@ -238,8 +238,8 @@ public struct Peripheral: Sendable {
238238

239239
public func writeValue(_ value: Data, for descriptor: CBDescriptor) -> AnyPublisher<Void, Error> {
240240
didWriteValueForDescriptor
241-
.filterFirstValueOrThrow(where: {
242-
$0.uuid == descriptor.uuid
241+
.filterFirstValueOrThrow(where: { [uuid = descriptor.uuid] in
242+
$0.uuid == uuid
243243
})
244244
.map { _ in }
245245
.handleEvents(receiveSubscription: { [_writeValueForDescriptor] _ in
@@ -292,7 +292,7 @@ public struct Peripheral: Sendable {
292292
discoverCharacteristics(withUUIDs: [characteristicUUID], inServiceWithUUID: serviceUUID)
293293
.tryMap { characteristics in
294294
// assume core bluetooth won't send us a characteristic list without the characteristic we expect
295-
guard let characteristic = characteristics.first(where: { characteristic in characteristic.uuid == characteristicUUID }) else {
295+
guard let characteristic = characteristics.first(where: { c in c.uuid == characteristicUUID }) else {
296296
throw PeripheralError.characteristicNotFound(characteristicUUID)
297297
}
298298
return characteristic
@@ -405,8 +405,8 @@ public struct Peripheral: Sendable {
405405
public func listenForUpdates(on characteristic: CBCharacteristic) -> AnyPublisher<Data?, Error> {
406406
didUpdateValueForCharacteristic
407407
// not limiting to `.first()` here as callers may want long-lived listening for value changes
408-
.filter({ (readCharacteristic, error) -> Bool in
409-
return readCharacteristic.uuid == characteristic.uuid
408+
.filter({ [uuid = characteristic.uuid] (readCharacteristic, error) -> Bool in
409+
readCharacteristic.uuid == uuid
410410
})
411411
.selectValueOrThrowError()
412412
.map(\.value)
@@ -438,8 +438,8 @@ public struct Peripheral: Sendable {
438438
self.listenForUpdates(on: characteristic),
439439

440440
didUpdateNotificationState
441-
.filterFirstValueOrThrow(where: {
442-
$0.uuid == characteristic.uuid
441+
.filterFirstValueOrThrow(where: { [uuid = characteristic.uuid] in
442+
$0.uuid == uuid
443443
})
444444
.ignoreOutput(setOutputType: Data?.self)
445445
)

0 commit comments

Comments
 (0)