Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
NickKibish committed Dec 4, 2023
2 parents fdef4b0 + b5252e5 commit 9558462
Show file tree
Hide file tree
Showing 551 changed files with 1,729 additions and 534 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Script"
scriptText = "export PATH=/usr/local/bin:$PATH&#10;cd &quot;$WORKSPACE_PATH&quot;/../../../IOS-BLE-Library/&#10;&#10;python3 code_gen/code_gen.py Sources&#10;">
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
Expand Down
61 changes: 12 additions & 49 deletions .swiftpm/xcode/xcshareddata/xcschemes/iOS-BLE-Library.xcscheme
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1420"
version = "1.3">
LastUpgradeVersion = "1500"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Script"
scriptText = "export PATH=/usr/local/bin:$PATH&#10;cd &quot;$WORKSPACE_PATH&quot;/../../../IOS-BLE-Library/&#10;&#10;python3 code_gen/code_gen.py Sources&#10;">
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
Expand All @@ -20,54 +29,14 @@
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "iOS-BLE-LibraryTests"
BuildableName = "iOS-BLE-LibraryTests"
BlueprintName = "iOS-BLE-LibraryTests"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CoreBluetoothMock-Collection"
BuildableName = "CoreBluetoothMock-Collection"
BlueprintName = "CoreBluetoothMock-Collection"
ReferencedContainer = "container:../CoreBluetoothMock-Collection">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "iOS-BLE-Library"
BuildableName = "iOS-BLE-Library"
BlueprintName = "iOS-BLE-Library"
ReferencedContainer = "container:">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
</Testables>
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -79,12 +48,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<CommandLineArguments>
<CommandLineArgument
argument = "-Xswiftc MOCK"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,8 @@ pod 'iOS-BLE-Library-Mock', '~> 0.1.3'

As of this writing, we are not recommending this library for external use. It is used by both our Private and Public / Open-Source apps, hence the need to make it public as well. But for now we haven't settled on the API - we're still learning from all of Apple's new technologies such as Actors and Async / Await, therefore, it is likely big changes might be required as we move forward.

# TBD
* Documentation
* It will be added but the API is copying the CoreBluetooth API, so it should be easy to understand.
* Examples
* Currently examples can be found in iOS-nRF-Toolbox in the [develop](https://github.com/NordicSemiconductor/IOS-nRF-Toolbox/tree/develop) branch.
* Unit Tests
* Create two versions of the library:
* CoreBluetooth API compatible
* [CoreBluetoothMock](https://github.com/NordicSemiconductor/IOS-CoreBluetooth-Mock) API compatible
* Currently the library is using the CoreBluetoothMock API. It can be not compatible with other libraries that relies on the CoreBluetooth API.
# Documentation & Examples
Please check the [Documentation Page](https://nordicsemiconductor.github.io/IOS-BLE-Library/documentation/ios_ble_library/) to start using the library.

Also you can check [iOS-nRF-Toolbox](https://github.com/NordicSemiconductor/IOS-nRF-Toolbox/tree/develop) to find more examples.

87 changes: 39 additions & 48 deletions Sources/iOS-BLE-Library-Mock/Alias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,59 +38,50 @@ import CoreBluetoothMock
// disabled for Xcode 12.5 beta
//typealias CBPeer = CBMPeer
//typealias CBAttribute = CBMAttribute
public typealias CBCentralManagerFactory = CBMCentralManagerFactory
public typealias CBUUID = CBMUUID
public typealias CBError = CBMError
public typealias CBATTError = CBMATTError
public typealias CBManagerState = CBMManagerState
public typealias CBPeripheralState = CBMPeripheralState
public typealias CBCentralManager = CBMCentralManager
public typealias CBCentralManagerDelegate = CBMCentralManagerDelegate
public typealias CBPeripheral = CBMPeripheral
public typealias CBPeripheralDelegate = CBMPeripheralDelegate
public typealias CBService = CBMService
public typealias CBCharacteristic = CBMCharacteristic
public typealias CBCharacteristicWriteType = CBMCharacteristicWriteType
public typealias CBCharacteristicProperties = CBMCharacteristicProperties
public typealias CBDescriptor = CBMDescriptor
public typealias CBConnectionEvent = CBMConnectionEvent
public typealias CBCentralManagerFactory = CBMCentralManagerFactory
public typealias CBUUID = CBMUUID
public typealias CBError = CBMError
public typealias CBATTError = CBMATTError
public typealias CBManagerState = CBMManagerState
public typealias CBPeripheralState = CBMPeripheralState
public typealias CBCentralManager = CBMCentralManager
public typealias CBCentralManagerDelegate = CBMCentralManagerDelegate
public typealias CBPeripheral = CBMPeripheral
public typealias CBPeripheralDelegate = CBMPeripheralDelegate
public typealias CBService = CBMService
public typealias CBCharacteristic = CBMCharacteristic
public typealias CBCharacteristicWriteType = CBMCharacteristicWriteType
public typealias CBCharacteristicProperties = CBMCharacteristicProperties
public typealias CBDescriptor = CBMDescriptor
public typealias CBConnectionEvent = CBMConnectionEvent
public typealias CBConnectionEventMatchingOption = CBMConnectionEventMatchingOption
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)
public typealias CBL2CAPPSM = CBML2CAPPSM
public typealias CBL2CAPPSM = CBML2CAPPSM
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)
public typealias CBL2CAPChannel = CBML2CAPChannel
public typealias CBL2CAPChannel = CBML2CAPChannel

public let CBCentralManagerScanOptionAllowDuplicatesKey =
CBMCentralManagerScanOptionAllowDuplicatesKey
public let CBCentralManagerOptionShowPowerAlertKey = CBMCentralManagerOptionShowPowerAlertKey
public let CBCentralManagerOptionRestoreIdentifierKey = CBMCentralManagerOptionRestoreIdentifierKey
public let CBCentralManagerScanOptionSolicitedServiceUUIDsKey =
CBMCentralManagerScanOptionSolicitedServiceUUIDsKey
public let CBConnectPeripheralOptionStartDelayKey = CBMConnectPeripheralOptionStartDelayKey
public let CBCentralManagerScanOptionAllowDuplicatesKey = CBMCentralManagerScanOptionAllowDuplicatesKey
public let CBCentralManagerOptionShowPowerAlertKey = CBMCentralManagerOptionShowPowerAlertKey
public let CBCentralManagerOptionRestoreIdentifierKey = CBMCentralManagerOptionRestoreIdentifierKey
public let CBCentralManagerScanOptionSolicitedServiceUUIDsKey = CBMCentralManagerScanOptionSolicitedServiceUUIDsKey
public let CBConnectPeripheralOptionStartDelayKey = CBMConnectPeripheralOptionStartDelayKey
#if !os(macOS)
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public let CBConnectPeripheralOptionRequiresANCS = CBMConnectPeripheralOptionRequiresANCS
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public let CBConnectPeripheralOptionRequiresANCS = CBMConnectPeripheralOptionRequiresANCS
#endif
public let CBCentralManagerRestoredStatePeripheralsKey =
CBMCentralManagerRestoredStatePeripheralsKey
public let CBCentralManagerRestoredStateScanServicesKey =
CBMCentralManagerRestoredStateScanServicesKey
public let CBCentralManagerRestoredStateScanOptionsKey =
CBMCentralManagerRestoredStateScanOptionsKey
public let CBCentralManagerRestoredStatePeripheralsKey = CBMCentralManagerRestoredStatePeripheralsKey
public let CBCentralManagerRestoredStateScanServicesKey = CBMCentralManagerRestoredStateScanServicesKey
public let CBCentralManagerRestoredStateScanOptionsKey = CBMCentralManagerRestoredStateScanOptionsKey

public let CBAdvertisementDataLocalNameKey = CBMAdvertisementDataLocalNameKey
public let CBAdvertisementDataServiceUUIDsKey = CBMAdvertisementDataServiceUUIDsKey
public let CBAdvertisementDataIsConnectable = CBMAdvertisementDataIsConnectable
public let CBAdvertisementDataTxPowerLevelKey = CBMAdvertisementDataTxPowerLevelKey
public let CBAdvertisementDataServiceDataKey = CBMAdvertisementDataServiceDataKey
public let CBAdvertisementDataManufacturerDataKey = CBMAdvertisementDataManufacturerDataKey
public let CBAdvertisementDataOverflowServiceUUIDsKey = CBMAdvertisementDataOverflowServiceUUIDsKey
public let CBAdvertisementDataSolicitedServiceUUIDsKey =
CBMAdvertisementDataSolicitedServiceUUIDsKey
public let CBAdvertisementDataLocalNameKey = CBMAdvertisementDataLocalNameKey
public let CBAdvertisementDataServiceUUIDsKey = CBMAdvertisementDataServiceUUIDsKey
public let CBAdvertisementDataIsConnectable = CBMAdvertisementDataIsConnectable
public let CBAdvertisementDataTxPowerLevelKey = CBMAdvertisementDataTxPowerLevelKey
public let CBAdvertisementDataServiceDataKey = CBMAdvertisementDataServiceDataKey
public let CBAdvertisementDataManufacturerDataKey = CBMAdvertisementDataManufacturerDataKey
public let CBAdvertisementDataOverflowServiceUUIDsKey = CBMAdvertisementDataOverflowServiceUUIDsKey
public let CBAdvertisementDataSolicitedServiceUUIDsKey = CBMAdvertisementDataSolicitedServiceUUIDsKey

public let CBConnectPeripheralOptionNotifyOnConnectionKey =
CBMConnectPeripheralOptionNotifyOnConnectionKey
public let CBConnectPeripheralOptionNotifyOnDisconnectionKey =
CBMConnectPeripheralOptionNotifyOnDisconnectionKey
public let CBConnectPeripheralOptionNotifyOnNotificationKey =
CBMConnectPeripheralOptionNotifyOnNotificationKey
public let CBConnectPeripheralOptionNotifyOnConnectionKey = CBMConnectPeripheralOptionNotifyOnConnectionKey
public let CBConnectPeripheralOptionNotifyOnDisconnectionKey = CBMConnectPeripheralOptionNotifyOnDisconnectionKey
public let CBConnectPeripheralOptionNotifyOnNotificationKey = CBMConnectPeripheralOptionNotifyOnNotificationKey
64 changes: 30 additions & 34 deletions Sources/iOS-BLE-Library-Mock/CentralManager/CentralManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ extension CentralManager {
public var localizedDescription: String {
switch self {
case .wrongManager:
return
"Incorrect manager instance provided. Delegate must be of type ReactiveCentralManagerDelegate."
return "Incorrect manager instance provided. Delegate must be of type ReactiveCentralManagerDelegate."
case .badState(let state):
return "Bad state: \(state)."
case .unknownError:
Expand Down Expand Up @@ -55,7 +54,7 @@ private class Observer: NSObject {
}

/// A Custom Central Manager class.
///
///
/// It wraps the standard CBCentralManager and has similar API. However, instead of using delegate, it uses publishers, thus bringing the reactive programming paradigm to the CoreBluetooth framework.
public class CentralManager {
private let isScanningSubject = CurrentValueSubject<Bool, Never>(false)
Expand All @@ -64,7 +63,7 @@ public class CentralManager {

/// The underlying CBCentralManager instance.
public let centralManager: CBCentralManager

/// The reactive delegate for the ``centralManager``.
public let centralManagerDelegate: ReactiveCentralManagerDelegate

Expand All @@ -74,12 +73,10 @@ public class CentralManager {
/// - queue: The queue to perform operations on. Default is the main queue.
public init(
centralManagerDelegate: ReactiveCentralManagerDelegate =
ReactiveCentralManagerDelegate(), queue: DispatchQueue = .main,
options: [String: Any]? = nil
ReactiveCentralManagerDelegate(), queue: DispatchQueue = .main, options: [String : Any]? = nil
) {
self.centralManagerDelegate = centralManagerDelegate
self.centralManager = CBMCentralManagerFactory.instance(
delegate: centralManagerDelegate, queue: queue)
self.centralManager = CBMCentralManagerFactory.instance(delegate: centralManagerDelegate, queue: queue)
observer.setup()
}

Expand Down Expand Up @@ -112,17 +109,17 @@ extension CentralManager {
/// If the peripheral was disconnected successfully, the publisher finishes without error.
/// If the connection was unsuccessful or disconnection returns an error (e.g., peripheral disconnected unexpectedly),
/// the publisher finishes with an error.
///
/// Use ``CentralManager/connect(_:options:)`` to connect to a peripheral.
/// The returned publisher will emit the connected peripheral or an error if the connection fails.
/// The publisher will not complete until the peripheral is disconnected.
/// If the connection fails, or the peripheral is unexpectedly disconnected, the publisher will fail with an error.
///
/// ```swift
/// centralManager.connect(peripheral)
/// .sink { completion in
/// switch completion {
/// case .finished:
///
/// Use ``CentralManager/connect(_:options:)`` to connect to a peripheral.
/// The returned publisher will emit the connected peripheral or an error if the connection fails.
/// The publisher will not complete until the peripheral is disconnected.
/// If the connection fails, or the peripheral is unexpectedly disconnected, the publisher will fail with an error.
///
/// ```swift
/// centralManager.connect(peripheral)
/// .sink { completion in
/// switch completion {
/// case .finished:
/// print("Peripheral disconnected successfully")
/// case .failure(let error):
/// print("Error: \(error)")
Expand Down Expand Up @@ -155,16 +152,15 @@ extension CentralManager {
.bluetooth {
self.centralManager.connect(peripheral, options: options)
}
.autoconnect()
.eraseToAnyPublisher()
.autoconnect()
.eraseToAnyPublisher()
}

/// Cancels the connection with the specified peripheral.
/// - Parameter peripheral: The peripheral to disconnect from.
/// - Returns: A publisher that emits the disconnected peripheral.
public func cancelPeripheralConnection(_ peripheral: CBPeripheral) -> AnyPublisher<
CBPeripheral, Error
> {
public func cancelPeripheralConnection(_ peripheral: CBPeripheral) -> AnyPublisher<CBPeripheral, Error>
{
return self.disconnectedPeripheralsChannel
.tryFilter { r in
guard r.0.identifier == peripheral.identifier else {
Expand All @@ -179,17 +175,17 @@ extension CentralManager {
}
.map { $0.0 }
.first()
.bluetooth {
self.centralManager.cancelPeripheralConnection(peripheral)
}
.autoconnect()
.eraseToAnyPublisher()
.bluetooth {
self.centralManager.cancelPeripheralConnection(peripheral)
}
.autoconnect()
.eraseToAnyPublisher()
}
}

// MARK: Retrieving Lists of Peripherals
extension CentralManager {
#warning("check `connect` method")
#warning("check `connect` method")
/// Returns a list of the peripherals connected to the system whose
/// services match a given set of criteria.
///
Expand Down Expand Up @@ -222,9 +218,9 @@ extension CentralManager {
extension CentralManager {
#warning("Question: Should we throw an error if the scan is already running?")
/// Initiates a scan for peripherals with the specified services.
///
///
/// Calling this method stops an ongoing scan if it is already running and finishes the publisher returned by ``scanForPeripherals(withServices:)``.
///
///
/// - Parameter services: The services to scan for.
/// - Returns: A publisher that emits scan results or an error.
public func scanForPeripherals(withServices services: [CBUUID]?)
Expand Down Expand Up @@ -254,8 +250,8 @@ extension CentralManager {
.bluetooth {
self.centralManager.scanForPeripherals(withServices: services)
}
.autoconnect()
.eraseToAnyPublisher()
.autoconnect()
.eraseToAnyPublisher()
}

/// Stops an ongoing scan for peripherals.
Expand Down
Loading

0 comments on commit 9558462

Please sign in to comment.