Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filter for and services #24

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Sources/RxCBCentral/RxPeripheral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public protocol RxPeripheral: AnyObject {
/// The data returned will be processed by the `Preprocessor` given when registering
/// for notifications for this `characteristic`, if one was provided.
func notificationData(for characteristic: CBUUID) -> Observable<Data>

/// Validate if service exist
func hasService(service: CBUUID) -> Observable<Bool>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition, can you use modify this interface to use more Swift style naming, like:

func hasService(_ service: CBUUID) -> Observable<Bool>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func hasService(service: CBUUID) -> Observable<Bool>
func hasService(_ service: CBUUID) -> Observable<Bool>


}

/// Aggregates Data for the purpose of demarcation.
Expand Down
1 change: 1 addition & 0 deletions Sources/RxCBCentral/core/CBPeripheralType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public protocol CBPeripheralType: AnyObject {
func maximumWriteValueLength(for type: CBCharacteristicWriteType) -> Int

func discoverServices(_ serviceUUIDs: [CBUUID]?)
func discoverDescriptors(for characteristic: CBCharacteristic)
func discoverCharacteristics(_ characteristicUUIDs: [CBUUID]?, for service: CBService)

func readValue(for characteristic: CBCharacteristic)
Expand Down
76 changes: 73 additions & 3 deletions Sources/RxCBCentral/core/RxPeripheralImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,14 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
return
didDiscoverServicesSubject
.map { (services: [CBService], error: Error?) -> (CBService?, Error?) in
print("RFN ",services.count, services)
print("RFN ",services.first?.uuid.uuidString, service.uuidString)
Comment on lines +201 to +202
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Printing is helpful for debugging purposes but we don't want to ship the library with live print statements. Please remove or add these to the logger.

Comment on lines +201 to +202
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN ",services.count, services)
print("RFN ",services.first?.uuid.uuidString, service.uuidString)

let matchingService = services.first { $0.uuid.uuidString == service.uuidString }
return (matchingService, error)
}
.take(1)
.flatMapLatest { (matchingService: CBService?, error: Error?) -> Observable<([CBCharacteristic], Error?)> in
print("MATCHINGSERVICE :",matchingService)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("MATCHINGSERVICE :",matchingService)

guard let matchingService = matchingService else {
RxCBLogger.sharedInstance.log("Error: service not found")
return Observable.error(GattError.serviceNotFound)
Expand All @@ -204,14 +207,36 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
return Observable.error(error)
}

print("CHARACTERISTIC TO SEARCH: ",characteristic)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("CHARACTERISTIC TO SEARCH: ",characteristic)

self.peripheral.discoverCharacteristics([characteristic], for: matchingService)

return self.didDiscoverCharacteristicsSubject.asObservable()
}
.filter
{ print("FILTER for")
print($0,$1)
for c in $0{
print(c.uuid.uuidString, characteristic.uuidString)
if(c.uuid.uuidString == characteristic.uuidString){
return true
}
}
return false
}
.take(1)
.map { (characteristics: [CBCharacteristic], error: Error?) -> (CBCharacteristic?, Error?) in
let characteristic = characteristics.first { $0.uuid.uuidString == characteristic.uuidString }
return (characteristic, error)
print("RFN characteristics ",characteristics.count, characteristics)
for c in characteristics {
print(c.uuid.uuidString, characteristic.uuidString)
if(c.uuid.uuidString == characteristic.uuidString){
return (c, error)
}
}
print("not found , what to do, raise an error")
return (characteristics.first,GattError.characteristicNotFound)
// print("RFN ",characteristics.first?.uuid.uuidString , characteristic.uuidString)
// let characteristic = characteristics.first { $0.uuid.uuidString == characteristic.uuidString }
// return (characteristic, error)
Comment on lines +235 to +246
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup required

Comment on lines +235 to +246
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN characteristics ",characteristics.count, characteristics)
for c in characteristics {
print(c.uuid.uuidString, characteristic.uuidString)
if(c.uuid.uuidString == characteristic.uuidString){
return (c, error)
}
}
print("not found , what to do, raise an error")
return (characteristics.first,GattError.characteristicNotFound)
// print("RFN ",characteristics.first?.uuid.uuidString , characteristic.uuidString)
// let characteristic = characteristics.first { $0.uuid.uuidString == characteristic.uuidString }
// return (characteristic, error)
for c in characteristics where c.uuid.uuidString == characteristic.uuidString {
return (c, error)
}
return (characteristics.first, GattError.characteristicNotFound)

}
.do(onNext: { [weak self] (_, error: Error?) in
if let self = self, error == nil {
Expand All @@ -224,6 +249,7 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
}
})
.flatMapLatest { (matchingCharacteristic: CBCharacteristic?, error: Error?) -> Observable<(CBCharacteristic, Error?)> in
print("RFN \(#line)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN \(#line)")

guard let matchingCharacteristic = matchingCharacteristic else {
RxCBLogger.sharedInstance.log("Error: characteristic not found")
return Observable.error(GattError.characteristicNotFound)
Expand All @@ -235,14 +261,15 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
}
// let CB give an error if property isn't notify-able
self.peripheral.setNotifyValue(true, for: matchingCharacteristic)

print("RFN \(#line)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN \(#line)")

return self.didUpdateValueForCharacteristicSubject.asObservable()
}
.take(1)
.flatMapLatest { (_, error: Error?) -> Completable in
if let error = error {
return Observable.error(error).asCompletable()
}
print("RFN completed")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN completed")

return Observable.empty().asCompletable()
}
.take(1)
Expand Down Expand Up @@ -274,6 +301,36 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
.filterNil()
}

public func hasService(service: CBUUID) -> Observable<Bool> {
return
didDiscoverServicesSubject
.map { (services: [CBService], error: Error?) -> (CBService?, Error?) in
print("RFN ",services.count, services)
print("RFN ",services.first?.uuid.uuidString, service.uuidString)
Comment on lines +324 to +325
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print("RFN ",services.count, services)
print("RFN ",services.first?.uuid.uuidString, service.uuidString)

let matchingService = services.first { $0.uuid.uuidString == service.uuidString }
return (matchingService, error)
}
.take(1)
.flatMapLatest { (matchingService: CBService?, error: Error?) -> Observable<Bool> in
print("MATCHINGSERVICE :",matchingService)
guard let matchingService = matchingService else {
RxCBLogger.sharedInstance.log("Error: service not found")
return Observable.just(false)
}

if let error = error {
RxCBLogger.sharedInstance.log("Error: \(error.localizedDescription)")
return Observable.just(false)
}

return Observable.just(true)
}.do(onSubscribe: {
self.peripheral.discoverServices([service])
})

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

}


// MARK: - CBPeripheralDelegate

public func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
Expand All @@ -294,9 +351,22 @@ class RxPeripheralImpl: NSObject, RxPeripheral, CBPeripheralDelegate {
didDiscoverCharacteristicsSubject.onNext(characteristicsData)
}

public func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
guard let desc = characteristic.descriptors else { return }
for des in desc {
// des.setValue(<#T##value: Any?##Any?#>, forKey: <#T##String#>)
print("BEGIN:SPAKA DESCRIPTOR========>\(des)")
// self.peripheral.setNotifyValue(true, for: characteristic)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup required

}
}

/// Invoked when you retrieve a characteristic’s value, or when the peripheral notifies you the value has changed
public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
let valueData = (characteristic, error)
if characteristic.value != nil {
let value = characteristic.value?.subdata(in: Range(1...2)).withUnsafeBytes {$0.load(as: UInt8.self)}
print("didUpdateValueFor Characteristic", characteristic, " value:", value ?? "No data 324")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete, since we don't want to ship the library with live print statements

didUpdateValueForCharacteristicSubject.onNext(valueData)
}

Expand Down
7 changes: 7 additions & 0 deletions Sources/RxCBCentral/mocks/Mocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ public class BluetoothDetectorTypeMock: BluetoothDetectorType {
}

public class CBPeripheralTypeMock: CBPeripheralType {
public func discoverDescriptors(for characteristic: CBCharacteristic) {
print("ok")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please arrange here.

}


private var _doneInit = false
public init(identifier: UUID = UUID(), state: CBPeripheralState = .disconnected) {
Expand Down Expand Up @@ -566,6 +570,9 @@ public class RxPeripheralMock: RxPeripheral {
}
return Observable.empty()
}
public func hasService(service: CBUUID) -> Observable<Bool>{
return Observable.just(true)
}
}

class CBCentralManagerTypeMock: CBCentralManagerType {
Expand Down