Skip to content

Commit 9484ab2

Browse files
committed
Merge pull request #27 from Polidea/feature/state_restoration
Feature/state restoration
2 parents 4b6787f + c93861c commit 9484ab2

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ We really encourage you to use these versions of methods in order to make your c
250250
### Other useful functionalities
251251
Here you'll find other useful functionalities of library
252252

253+
#### Bluetooth state restoration
254+
By giving proper identifier to `BluetoothManager` in constructor(`options` property), you can achieve state restoration functionality. Later, just make sure to subscribe to `listenOnRestoredState` observable, and inspect `RestoredState` instance, which consists any useful info about restored state.
255+
253256
#### Monitoring state of Bluetooth
254257
Used earlier `rx_state` is very useful function on `BluetoothManager`. While subscribed, it emits `Next` immediately with current `CBCentralManagerState`.
255258
After that, it emits new element after state changes.

RxBluetoothKit.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
2666FE481CCE4732005E81CE /* RxCBCentralManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1299C171CBE3DEE005DEA5B /* RxCBCentralManager.swift */; };
8989
2666FE491CCE4732005E81CE /* BluetoothManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1299C0E1CBE3DEE005DEA5B /* BluetoothManager.swift */; };
9090
2666FE4A1CCE4732005E81CE /* AdvertisementData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1299C0C1CBE3DEE005DEA5B /* AdvertisementData.swift */; };
91+
26F3034B1CF0D49D00D74EBF /* RestoredState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F3034A1CF0D49D00D74EBF /* RestoredState.swift */; };
9192
A10F298A1CDCD6E100593284 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2666FE5A1CCE65CD005E81CE /* RxSwift.framework */; };
9293
A10F298B1CDCD6E400593284 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2666FE5E1CCE65EE005E81CE /* RxSwift.framework */; };
9394
A10F29A11CDCD74B00593284 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A10F29921CDCD72200593284 /* Nimble.framework */; };
@@ -167,6 +168,7 @@
167168
2666FDAC1CCE4626005E81CE /* RxBluetoothKit OSXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RxBluetoothKit OSXTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
168169
2666FE5A1CCE65CD005E81CE /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/iOS/RxSwift.framework; sourceTree = SOURCE_ROOT; };
169170
2666FE5E1CCE65EE005E81CE /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/Mac/RxSwift.framework; sourceTree = SOURCE_ROOT; };
171+
26F3034A1CF0D49D00D74EBF /* RestoredState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoredState.swift; sourceTree = "<group>"; };
170172
A10F29901CDCD72200593284 /* RxTests.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxTests.framework; path = Carthage/Build/Mac/RxTests.framework; sourceTree = SOURCE_ROOT; };
171173
A10F29911CDCD72200593284 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/Mac/Quick.framework; sourceTree = SOURCE_ROOT; };
172174
A10F29921CDCD72200593284 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/Mac/Nimble.framework; sourceTree = SOURCE_ROOT; };
@@ -258,6 +260,7 @@
258260
A1299C171CBE3DEE005DEA5B /* RxCBCentralManager.swift */,
259261
A1299C0E1CBE3DEE005DEA5B /* BluetoothManager.swift */,
260262
A1299C0C1CBE3DEE005DEA5B /* AdvertisementData.swift */,
263+
26F3034A1CF0D49D00D74EBF /* RestoredState.swift */,
261264
);
262265
name = BluetoothManager;
263266
sourceTree = "<group>";
@@ -675,6 +678,7 @@
675678
2666FE4A1CCE4732005E81CE /* AdvertisementData.swift in Sources */,
676679
2666FE421CCE4732005E81CE /* Observable+Absorb.swift in Sources */,
677680
2666FE341CCE4732005E81CE /* ScannedPeripheral.swift in Sources */,
681+
26F3034B1CF0D49D00D74EBF /* RestoredState.swift in Sources */,
678682
);
679683
runOnlyForDeploymentPostprocessing = 0;
680684
};

Source/BluetoothManager.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,12 @@ public class BluetoothManager {
8585
code.
8686

8787
- parameter queue: Queue on which bluetooth callbacks are received. By default main thread is used.
88+
89+
- parameter options: An optional dictionary containing initialization options for a central manager.
90+
For more info about it please refer to [`Central Manager initialization options`](https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBCentralManager_Class/index.html)
8891
*/
89-
convenience public init(queue: dispatch_queue_t = dispatch_get_main_queue()) {
92+
convenience public init(queue: dispatch_queue_t = dispatch_get_main_queue(),
93+
options: [String : AnyObject]? = nil) {
9094
self.init(centralManager: RxCBCentralManager(queue: queue),
9195
queueScheduler: ConcurrentDispatchQueueScheduler(queue: queue))
9296
}
@@ -394,4 +398,15 @@ public class BluetoothManager {
394398
return Observable.just(peripheral)
395399
}
396400
}
401+
402+
/**
403+
Emits `RestoredState` instance, when state of `BluetoothManager` has been restored
404+
- Returns: Observable which emits next events state has been restored
405+
*/
406+
func listenOnRestoredState() -> Observable<RestoredState> {
407+
return centralManager
408+
.rx_willRestoreState
409+
.take(1)
410+
.map { RestoredState(restoredStateDictionary: $0, bluetoothManager: self) }
411+
}
397412
}

Source/RestoredState.swift

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// RestoredState.swift
3+
// RxBluetoothKit
4+
//
5+
// Created by Kacper Harasim on 21.05.2016.
6+
// Copyright © 2016 Polidea. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import CoreBluetooth
11+
12+
/**
13+
Convenience class which helps reading state of restored BluetoothManager
14+
*/
15+
public struct RestoredState {
16+
17+
/**
18+
Restored state dictionary
19+
*/
20+
public let restoredStateData: [String:AnyObject]
21+
22+
public unowned let bluetoothManager: BluetoothManager
23+
/**
24+
Creates restored state information based on CoreBluetooth's dictionary
25+
- parameter restoredState: Core Bluetooth's restored state data
26+
- parameter bluetoothManager: `BluetoothManager` instance of which state has been restored.
27+
*/
28+
init(restoredStateDictionary: [String:AnyObject], bluetoothManager: BluetoothManager) {
29+
self.restoredStateData = restoredStateDictionary
30+
self.bluetoothManager = bluetoothManager
31+
}
32+
33+
/**
34+
Array of `Peripheral` objects which have been restored. These are peripherals that were connected to the central manager (or had a connection pending) at the time the app was terminated by the system.
35+
*/
36+
public var peripherals: [Peripheral] {
37+
let objects = restoredStateData[CBCentralManagerRestoredStatePeripheralsKey] as? [AnyObject]
38+
guard let arrayOfAnyObjects = objects else { return [] }
39+
return arrayOfAnyObjects.flatMap { $0 as? CBPeripheral }
40+
.map { RxCBPeripheral(peripheral: $0) }
41+
.map { Peripheral(manager: bluetoothManager, peripheral: $0) }
42+
}
43+
44+
/**
45+
Dictionary that contains all of the peripheral scan options that were being used by the central manager at the time the app was terminated by the system.
46+
*/
47+
public var scanOptions: [String : AnyObject]? {
48+
return restoredStateData[CBCentralManagerRestoredStatePeripheralsKey] as? [String : AnyObject]
49+
}
50+
51+
/**
52+
Array of `Service` objects which have been restored. These are all the services the central manager was scanning for at the time the app was terminated by the system.
53+
*/
54+
public var services: [Service] {
55+
let objects = restoredStateData[CBCentralManagerRestoredStateScanServicesKey] as? [AnyObject]
56+
guard let arrayOfAnyObjects = objects else { return [] }
57+
return arrayOfAnyObjects.flatMap { $0 as? CBService }
58+
.map { RxCBService(service: $0) }
59+
.map { Service(peripheral: Peripheral(manager: bluetoothManager,
60+
peripheral: RxCBPeripheral(peripheral: $0.service.peripheral)), service: $0) }
61+
}
62+
}

Source/RxCBCentralManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class RxCBCentralManager: RxCentralManagerType {
3939

4040
- parameter queue: Dispatch queue on which callbacks are received.
4141
*/
42-
init(queue: dispatch_queue_t) {
43-
centralManager = CBCentralManager(delegate: internalDelegate, queue: queue)
42+
init(queue: dispatch_queue_t, options: [String : AnyObject]? = nil) {
43+
centralManager = CBCentralManager(delegate: internalDelegate, queue: queue, options: options)
4444
}
4545

4646
@objc private class InternalDelegate: NSObject, CBCentralManagerDelegate {

0 commit comments

Comments
 (0)