forked from Polidea/RxBluetoothKit
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mikołaj Piechocki
committed
Oct 30, 2020
1 parent
603b7a4
commit f12d57c
Showing
7 changed files
with
303 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
ExampleApp/ExampleApp/Screens/Peripheral/PeripheralView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import UIKit | ||
|
||
class PeripheralView: UIView { | ||
|
||
init() { | ||
super.init(frame: .zero) | ||
backgroundColor = .systemBackground | ||
setupLayout() | ||
} | ||
|
||
required init?(coder: NSCoder) { nil } | ||
|
||
// MARK: - Subviews | ||
|
||
let updateButton: UIButton = { | ||
let button = UIButton(type: .system) | ||
button.setTitle("Update", for: .normal) | ||
button.setImage(UIImage(systemName: "sun.min"), for: .normal) | ||
return button | ||
}() | ||
|
||
let readButton: UIButton = { | ||
let button = UIButton(type: .system) | ||
button.setTitle("Read", for: .normal) | ||
button.setImage(UIImage(systemName: "phone.fill.arrow.up.right"), for: .normal) | ||
return button | ||
}() | ||
|
||
let writeButton: UIButton = { | ||
let button = UIButton(type: .system) | ||
button.setTitle("Write", for: .normal) | ||
button.setImage(UIImage(systemName: "phone.fill.arrow.down.left"), for: .normal) | ||
return button | ||
}() | ||
|
||
let stackView: UIStackView = { | ||
let stackView = UIStackView() | ||
stackView.axis = .vertical | ||
stackView.spacing = 20.0 | ||
return stackView | ||
}() | ||
|
||
// MARK: - Private | ||
|
||
private func setupLayout() { | ||
stackView.translatesAutoresizingMaskIntoConstraints = false | ||
addSubview(stackView) | ||
[updateButton, readButton, writeButton].forEach(stackView.addArrangedSubview) | ||
|
||
NSLayoutConstraint.activate([ | ||
stackView.centerXAnchor.constraint(equalTo: centerXAnchor), | ||
stackView.centerYAnchor.constraint(equalTo: centerYAnchor), | ||
stackView.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor, constant: -32) | ||
]) | ||
} | ||
|
||
} |
41 changes: 41 additions & 0 deletions
41
ExampleApp/ExampleApp/Screens/Peripheral/PeripheralViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import UIKit | ||
|
||
class PeripheralViewController: UIViewController { | ||
|
||
init() { | ||
super.init(nibName: nil, bundle: nil) | ||
} | ||
|
||
required init?(coder: NSCoder) { nil } | ||
|
||
// MARK: - View | ||
|
||
private(set) lazy var peripheralView = PeripheralView() | ||
|
||
override func loadView() { | ||
view = peripheralView | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
peripheralView.updateButton.addTarget(self, action: #selector(handleUpdateButton), for: .touchUpInside) | ||
peripheralView.readButton.addTarget(self, action: #selector(handleReadButton), for: .touchUpInside) | ||
peripheralView.writeButton.addTarget(self, action: #selector(handleWriteButton), for: .touchUpInside) | ||
} | ||
|
||
// MARK: - Private | ||
|
||
@objc private func handleUpdateButton() { | ||
let controller = PeripheralUpdateViewController() | ||
navigationController?.pushViewController(controller, animated: true) | ||
} | ||
|
||
@objc private func handleReadButton() { | ||
let controller = PeripheralReadViewController() | ||
navigationController?.pushViewController(controller, animated: true) | ||
} | ||
|
||
@objc private func handleWriteButton() {} | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
ExampleApp/ExampleApp/Screens/PeripheralRead/PeripheralReadView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import UIKit | ||
|
||
class PeripheralReadView: UIView { | ||
|
||
init() { | ||
super.init(frame: .zero) | ||
backgroundColor = .systemBackground | ||
setupLayout() | ||
} | ||
|
||
required init?(coder: NSCoder) { nil } | ||
|
||
// MARK: - Subviews | ||
|
||
let serviceUuidTextField: UITextField = { | ||
let textField = UITextField() | ||
textField.placeholder = "Service UUID" | ||
return textField | ||
}() | ||
|
||
let characteristicUuidTextField: UITextField = { | ||
let textField = UITextField() | ||
textField.placeholder = "Characteristic UUID" | ||
return textField | ||
}() | ||
|
||
let valueTextField: UITextField = { | ||
let textField = UITextField() | ||
textField.placeholder = "Value (String)" | ||
return textField | ||
}() | ||
|
||
let advertiseButton: UIButton = { | ||
let button = UIButton(type: .system) | ||
button.setTitle("Advertise", for: .normal) | ||
button.setImage(UIImage(systemName: "wave.3.right"), for: .normal) | ||
return button | ||
}() | ||
|
||
let stackView: UIStackView = { | ||
let stackView = UIStackView() | ||
stackView.axis = .vertical | ||
stackView.spacing = 20.0 | ||
return stackView | ||
}() | ||
|
||
// MARK: - Private | ||
|
||
private func setupLayout() { | ||
stackView.translatesAutoresizingMaskIntoConstraints = false | ||
addSubview(stackView) | ||
[serviceUuidTextField, characteristicUuidTextField, valueTextField, advertiseButton].forEach(stackView.addArrangedSubview) | ||
|
||
NSLayoutConstraint.activate([ | ||
stackView.centerXAnchor.constraint(equalTo: centerXAnchor), | ||
stackView.centerYAnchor.constraint(equalTo: centerYAnchor), | ||
stackView.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor, constant: -32) | ||
]) | ||
} | ||
|
||
} |
98 changes: 98 additions & 0 deletions
98
ExampleApp/ExampleApp/Screens/PeripheralRead/PeripheralReadViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import CoreBluetooth | ||
import RxBluetoothKit | ||
import RxSwift | ||
import UIKit | ||
|
||
class PeripheralReadViewController: UIViewController { | ||
|
||
init() { | ||
super.init(nibName: nil, bundle: nil) | ||
} | ||
|
||
required init?(coder: NSCoder) { nil } | ||
|
||
// MARK: - View | ||
|
||
private(set) lazy var peripheralReadView = PeripheralReadView() | ||
|
||
override func loadView() { | ||
view = peripheralReadView | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
peripheralReadView.advertiseButton.addTarget(self, action: #selector(handleAdvertiseButton), for: .touchUpInside) | ||
} | ||
|
||
// MARK: - Private | ||
|
||
private let disposeBag = DisposeBag() | ||
private lazy var manager = PeripheralManager() | ||
private var characteristic: CBMutableCharacteristic? | ||
private var advertisement: Disposable? | ||
private var isAdvertising = false { | ||
didSet { | ||
let text = isAdvertising ? "Stop Advertising" : "Advertise" | ||
peripheralReadView.advertiseButton.setTitle(text, for: .normal) | ||
} | ||
} | ||
|
||
@objc private func handleAdvertiseButton() { | ||
isAdvertising ? handleAdvertisingStop() : handleAdvertisingStart() | ||
} | ||
|
||
private func handleAdvertisingStart() { | ||
guard let serviceUuidString = peripheralReadView.serviceUuidTextField.text, | ||
let characteristicUuidString = peripheralReadView.characteristicUuidTextField.text, | ||
let value = peripheralReadView.valueTextField.text else { return } | ||
|
||
let service = createService(uuidString: serviceUuidString) | ||
let characteristic = createCharacteristic(uuidString: characteristicUuidString, value: value) | ||
service.characteristics = [characteristic] | ||
|
||
startAdvertising(service: service) | ||
self.characteristic = characteristic | ||
} | ||
|
||
private func handleAdvertisingStop() { | ||
advertisement?.dispose() | ||
advertisement = nil | ||
characteristic = nil | ||
isAdvertising.toggle() | ||
} | ||
|
||
private func createService(uuidString: String) -> CBMutableService { | ||
let serviceUuid = CBUUID(string: uuidString) | ||
return CBMutableService(type: serviceUuid, primary: true) | ||
} | ||
|
||
private func createCharacteristic(uuidString: String, value: String) -> CBMutableCharacteristic { | ||
let characteristicUuid = CBUUID(string: uuidString) | ||
return CBMutableCharacteristic( | ||
type: characteristicUuid, | ||
properties: [.read], | ||
value: value.data(using: .utf8), | ||
permissions: [.readable] | ||
) | ||
} | ||
|
||
private func startAdvertising(service: CBMutableService) { | ||
let managerIsOn = manager.observeStateWithInitialValue() | ||
.filter { $0 == .poweredOn } | ||
|
||
advertisement = Observable.combineLatest(managerIsOn, Observable.just(manager)) { $1 } | ||
.flatMap { $0.add(service) } | ||
.flatMap { [manager] in manager.startAdvertising($0.advertisingData) } | ||
.subscribe( | ||
onNext: { [weak self] in | ||
print("advertising started! \($0)") | ||
self?.isAdvertising.toggle() | ||
}, | ||
onError: { [weak self] in | ||
AlertPresenter.presentError(with: $0.printable, on: self?.navigationController) | ||
} | ||
) | ||
} | ||
|
||
} |
Oops, something went wrong.