diff --git a/Podfile.lock b/Podfile.lock index 7a2e8de0..308aaee0 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -23,6 +23,12 @@ PODS: - Realm/Headers (4.3.2) - RealmSwift (4.3.2): - Realm (= 4.3.2) + - RxCocoa (6.2.0): + - RxRelay (= 6.2.0) + - RxSwift (= 6.2.0) + - RxRelay (6.2.0): + - RxSwift (= 6.2.0) + - RxSwift (6.2.0) - SVProgressHUD (2.2.5) - UICircularProgressRing (4.1.0) - WYPopoverController (0.2.2) @@ -45,6 +51,8 @@ DEPENDENCIES: - Quick - Realm (~> 4.3.2) - RealmSwift + - RxCocoa (~> 6.2.0) + - RxSwift (~> 6.2.0) - SVProgressHUD (~> 2.2.5) - UICircularProgressRing (~> 4.1.0) - WYPopoverController (~> 0.2.2) @@ -67,6 +75,9 @@ SPEC REPOS: - Quick - Realm - RealmSwift + - RxCocoa + - RxRelay + - RxSwift - SVProgressHUD - UICircularProgressRing - WYPopoverController @@ -99,11 +110,14 @@ SPEC CHECKSUMS: Quick: 6d9559f40647bc4d510103842ef2fdd882d753e2 Realm: 5e92902e2875dff4bb0fd02f67bb737c3d5db2bc RealmSwift: 9a360fc7bae04fc2e308a34fbd899d5faa2d6b22 + RxCocoa: 4baf94bb35f2c0ab31bc0cb9f1900155f646ba42 + RxRelay: e72dbfd157807478401ef1982e1c61c945c94b2f + RxSwift: d356ab7bee873611322f134c5f9ef379fa183d8f SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 UICircularProgressRing: 5a32c01f54474571b1e66e8fa050c0f83d6d981b WYPopoverController: 00d879c25bddd1fd873dcc21aa98c8308d7f1555 XMLDictionary: fa07b6ff422b3a91d47a5de9bc82e3fc04fbd167 -PODFILE CHECKSUM: 8636490deec038a8698cfeaa47fe53c04131ed21 +PODFILE CHECKSUM: fa38ccfd90caab8b342bbeb884f33901d78598f1 COCOAPODS: 1.10.1 diff --git a/SiliconLabsApp.xcodeproj/project.pbxproj b/SiliconLabsApp.xcodeproj/project.pbxproj index 3d11a182..c0bd27b1 100644 --- a/SiliconLabsApp.xcodeproj/project.pbxproj +++ b/SiliconLabsApp.xcodeproj/project.pbxproj @@ -787,10 +787,6 @@ 200818E427037214003ED510 /* SILAppSelectionHelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 200818E327037214003ED510 /* SILAppSelectionHelpViewController.m */; }; 205131182703636D00C27B92 /* SILAppTypeMotion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 205131162703636D00C27B92 /* SILAppTypeMotion.storyboard */; }; 205131192703636D00C27B92 /* SILAppTypeEnvironment.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 205131172703636D00C27B92 /* SILAppTypeEnvironment.storyboard */; }; - 2051311E2703638900C27B92 /* SILEnvironmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051311B2703638900C27B92 /* SILEnvironmentViewController.swift */; }; - 2051311F2703638900C27B92 /* SILMotionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051311D2703638900C27B92 /* SILMotionViewController.swift */; }; - 205131242703639400C27B92 /* SILMotionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205131212703639400C27B92 /* SILMotionViewModel.swift */; }; - 205131252703639400C27B92 /* SILEnvironmentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205131232703639400C27B92 /* SILEnvironmentViewModel.swift */; }; 205131E0270365A800C27B92 /* ThunderBoardTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20513127270365A700C27B92 /* ThunderBoardTypes.swift */; }; 205131E1270365A800C27B92 /* BleManager+DiscoveryFiltering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20513128270365A700C27B92 /* BleManager+DiscoveryFiltering.swift */; }; 205131E5270365A800C27B92 /* SILAppSelectionHelpViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2051312D270365A700C27B92 /* SILAppSelectionHelpViewController.xib */; }; @@ -817,7 +813,6 @@ 2051320E270365A800C27B92 /* DemoConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20513156270365A700C27B92 /* DemoConfiguration.swift */; }; 2051320F270365A800C27B92 /* SimulatedEnvironmentalDemoConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20513157270365A700C27B92 /* SimulatedEnvironmentalDemoConnection.swift */; }; 20513211270365A800C27B92 /* BatteryIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20513159270365A700C27B92 /* BatteryIcon.swift */; }; - 20513213270365A800C27B92 /* UIDevice+extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051315B270365A700C27B92 /* UIDevice+extensions.swift */; }; 20513214270365A800C27B92 /* StrengthCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051315C270365A700C27B92 /* StrengthCell.swift */; }; 20513215270365A800C27B92 /* BrightnessSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051315D270365A700C27B92 /* BrightnessSlider.swift */; }; 20513216270365A800C27B92 /* WeakTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2051315E270365A700C27B92 /* WeakTimer.swift */; }; @@ -1675,10 +1670,6 @@ 200818E327037214003ED510 /* SILAppSelectionHelpViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SILAppSelectionHelpViewController.m; sourceTree = ""; }; 205131162703636D00C27B92 /* SILAppTypeMotion.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SILAppTypeMotion.storyboard; sourceTree = ""; }; 205131172703636D00C27B92 /* SILAppTypeEnvironment.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SILAppTypeEnvironment.storyboard; sourceTree = ""; }; - 2051311B2703638900C27B92 /* SILEnvironmentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SILEnvironmentViewController.swift; sourceTree = ""; }; - 2051311D2703638900C27B92 /* SILMotionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SILMotionViewController.swift; sourceTree = ""; }; - 205131212703639400C27B92 /* SILMotionViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SILMotionViewModel.swift; sourceTree = ""; }; - 205131232703639400C27B92 /* SILEnvironmentViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SILEnvironmentViewModel.swift; sourceTree = ""; }; 20513127270365A700C27B92 /* ThunderBoardTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThunderBoardTypes.swift; sourceTree = ""; }; 20513128270365A700C27B92 /* BleManager+DiscoveryFiltering.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BleManager+DiscoveryFiltering.swift"; sourceTree = ""; }; 2051312C270365A700C27B92 /* WYPopoverController+SILHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WYPopoverController+SILHelpers.h"; sourceTree = ""; }; @@ -1706,7 +1697,6 @@ 20513156270365A700C27B92 /* DemoConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoConfiguration.swift; sourceTree = ""; }; 20513157270365A700C27B92 /* SimulatedEnvironmentalDemoConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimulatedEnvironmentalDemoConnection.swift; sourceTree = ""; }; 20513159270365A700C27B92 /* BatteryIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatteryIcon.swift; sourceTree = ""; }; - 2051315B270365A700C27B92 /* UIDevice+extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+extensions.swift"; sourceTree = ""; }; 2051315C270365A700C27B92 /* StrengthCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StrengthCell.swift; sourceTree = ""; }; 2051315D270365A700C27B92 /* BrightnessSlider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrightnessSlider.swift; sourceTree = ""; }; 2051315E270365A700C27B92 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = ""; }; @@ -2249,7 +2239,6 @@ 2051315E270365A700C27B92 /* WeakTimer.swift */, 2051313C270365A700C27B92 /* Logging.swift */, 2051316B270365A700C27B92 /* Throttle.swift */, - 2051315B270365A700C27B92 /* UIDevice+extensions.swift */, ); path = Utilities; sourceTree = ""; @@ -2453,8 +2442,6 @@ isa = PBXGroup; children = ( 80B5FF7F275F911E008F08A8 /* WifiCommissioning */, - 205131222703639400C27B92 /* Environment */, - 205131202703639400C27B92 /* Motion */, 1EFC76B426AEE0120035594E /* Blinky */, 1EFC76BC26AEE02A0035594E /* Throughput */, 1EFC767B26AEDFA40035594E /* GattConfigurator */, @@ -3975,38 +3962,6 @@ path = Warning; sourceTree = ""; }; - 2051311A2703638900C27B92 /* Environment */ = { - isa = PBXGroup; - children = ( - 2051311B2703638900C27B92 /* SILEnvironmentViewController.swift */, - ); - path = Environment; - sourceTree = ""; - }; - 2051311C2703638900C27B92 /* Motion */ = { - isa = PBXGroup; - children = ( - 2051311D2703638900C27B92 /* SILMotionViewController.swift */, - ); - path = Motion; - sourceTree = ""; - }; - 205131202703639400C27B92 /* Motion */ = { - isa = PBXGroup; - children = ( - 205131212703639400C27B92 /* SILMotionViewModel.swift */, - ); - path = Motion; - sourceTree = ""; - }; - 205131222703639400C27B92 /* Environment */ = { - isa = PBXGroup; - children = ( - 205131232703639400C27B92 /* SILEnvironmentViewModel.swift */, - ); - path = Environment; - sourceTree = ""; - }; 20513126270365A700C27B92 /* ThunderBoard */ = { isa = PBXGroup; children = ( @@ -4420,8 +4375,6 @@ isa = PBXGroup; children = ( 80B5FF93275F912F008F08A8 /* WifiCommissioning */, - 2051311A2703638900C27B92 /* Environment */, - 2051311C2703638900C27B92 /* Motion */, 1E973CF02672693400B5FC71 /* Blinky */, 1E4D8F4326035FE000924430 /* IOP Test App */, 1E26EC5C255019E0002FFAAB /* Advertiser */, @@ -5695,7 +5648,6 @@ 0C2FCB081F9A542300F4F259 /* SILAppearance.m in Sources */, 0C2FCB0A1F9A542300F4F259 /* SILBigRedButton.m in Sources */, 1E90F5F12476C3C90013AABD /* SILKeychainInfoViewController.swift in Sources */, - 2051311E2703638900C27B92 /* SILEnvironmentViewController.swift in Sources */, 1E4DB386266A71E000405BD2 /* SILLocalGattServerViewController.swift in Sources */, 80B5FF89275F911E008F08A8 /* SILWifiCommissioningWriteCommandType.swift in Sources */, 1E973CD6267268D100B5FC71 /* SILBlinkyPeripheralDelegate.swift in Sources */, @@ -5850,7 +5802,6 @@ 2051321F270365A800C27B92 /* DeviceExtensions.swift in Sources */, 20513241270365A800C27B92 /* UIImage+Color.swift in Sources */, 0C2FCB341F9A542300F4F259 /* SILPopoverViewController.m in Sources */, - 205131252703639400C27B92 /* SILEnvironmentViewModel.swift in Sources */, 20513247270365A800C27B92 /* MotionSenseBoardDemoViewController.swift in Sources */, 0C2FCB351F9A542300F4F259 /* SILThermometerSegmentedControl.m in Sources */, 1EC1F1E2260CE96800508552 /* SILDiscoverTestConnectionParameters.swift in Sources */, @@ -5970,7 +5921,6 @@ 20513268270365A800C27B92 /* RGBCell.swift in Sources */, 1E4D8F5B26035FE000924430 /* SILIOPTesterViewController.swift in Sources */, 80B5FFA0275F912F008F08A8 /* SILWifiCommissioningDisconnectPopup.swift in Sources */, - 20513213270365A800C27B92 /* UIDevice+extensions.swift in Sources */, 2051320E270365A800C27B92 /* DemoConfiguration.swift in Sources */, 1E56B2222636EF96004F3EA6 /* SILIOPSecurityTestHelper.swift in Sources */, 1E4DB3B4266A720600405BD2 /* SILGattConfiguratorDescriptorButtonCellView.swift in Sources */, @@ -6067,7 +6017,6 @@ 1394F95E2566BD4400795E5A /* SILBigButton.swift in Sources */, 1EC1F274260CEBFE00508552 /* SILOTAAckTestCase.swift in Sources */, 1E4DB375266A71AE00405BD2 /* SILDemoNavigationViewController.swift in Sources */, - 2051311F2703638900C27B92 /* SILMotionViewController.swift in Sources */, 205131E8270365A800C27B92 /* EnvironmentalDemoConnection.swift in Sources */, 133D39C32554514600BFB484 /* SILAdvertiserNotification.swift in Sources */, 1E3FC7D8252B5E40002F740D /* UITextField+DoneButton.swift in Sources */, @@ -6077,7 +6026,6 @@ 0C2FCB671F9A542300F4F259 /* SILConstants.m in Sources */, 1EABF868251B7511006358C8 /* SILCharacteristicWriteViewController.swift in Sources */, 4C3BA289240D58DF00CF3268 /* SILKeychainViewController.swift in Sources */, - 205131242703639400C27B92 /* SILMotionViewModel.swift in Sources */, 1EFC766D26AEDF770035594E /* SILGattXmlMarkerType.swift in Sources */, 20513215270365A800C27B92 /* BrightnessSlider.swift in Sources */, 1E26EC86255019E0002FFAAB /* SILAdvertiserTypeCellView.swift in Sources */, @@ -6624,7 +6572,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_RESOURCE_RULES_PATH = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 46; + CURRENT_PROJECT_VERSION = 48; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 52444FG85C; DISPLAY_NAME = "EFR Connect"; @@ -6634,7 +6582,7 @@ INFOPLIST_FILE = "$(SRCROOT)/SiliconLabsApp/SupportingFiles/BlueGecko/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; PRODUCT_BUNDLE_IDENTIFIER = com.silabs.BlueGeckoDemoApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -6658,7 +6606,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_RESOURCE_RULES_PATH = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 46; + CURRENT_PROJECT_VERSION = 48; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 52444FG85C; DISPLAY_NAME = "EFR Connect"; @@ -6667,7 +6615,7 @@ INFOPLIST_FILE = "$(SRCROOT)/SiliconLabsApp/SupportingFiles/BlueGecko/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; PRODUCT_BUNDLE_IDENTIFIER = com.silabs.BlueGeckoDemoApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/SiliconLabsApp/ThunderBoard/Demos/Selection/NavBar.swift b/SiliconLabsApp/ThunderBoard/Demos/Selection/NavBar.swift index 986aebff..b941f181 100644 --- a/SiliconLabsApp/ThunderBoard/Demos/Selection/NavBar.swift +++ b/SiliconLabsApp/ThunderBoard/Demos/Selection/NavBar.swift @@ -9,16 +9,6 @@ import UIKit class NavBar: UIView { - - - @IBOutlet weak var height: NSLayoutConstraint! - - override func layoutSubviews() { - super.layoutSubviews() - if UIDevice.current.hasNoth { - height.constant = 148 - } - } override func draw(_ rect: CGRect) { super.draw(rect) diff --git a/SiliconLabsApp/ThunderBoard/Utilities/UIDevice+extensions.swift b/SiliconLabsApp/ThunderBoard/Utilities/UIDevice+extensions.swift deleted file mode 100644 index 85a12f58..00000000 --- a/SiliconLabsApp/ThunderBoard/Utilities/UIDevice+extensions.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// UIDevice+extensions.swift -// Thunderboard -// -// Created by Jan Wisniewski on 17/03/2020. -// Copyright © 2020 Silicon Labs. All rights reserved. -// - -import Foundation -import UIKit - -public -extension UIDevice { - public var hasNoth: Bool { - if UIDevice().userInterfaceIdiom == .phone { - switch UIScreen.main.nativeBounds.height { - case 1136: - return false - case 1334: - return false - case 1920, 2208: - return false - case 2436: - return true - case 2688: - return true - case 1792: - return true - default: - return true - } - } else { - return false - } - } -} diff --git a/SiliconLabsApp/ViewControllers/Environment/SILEnvironmentViewController.swift b/SiliconLabsApp/ViewControllers/Environment/SILEnvironmentViewController.swift deleted file mode 100644 index f1855079..00000000 --- a/SiliconLabsApp/ViewControllers/Environment/SILEnvironmentViewController.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// SILEnvironmentViewController.swift -// BlueGecko -// -// Created by Anastazja Gradowska on 16/09/2021. -// Copyright © 2021 SiliconLabs. All rights reserved. -// - -import Foundation - -class SILEnvironmentViewController: UIViewController, UIGestureRecognizerDelegate { - @IBOutlet var navigationBar: UIView! - private var viewModel: SILEnvironmentViewModel! - @IBOutlet weak var peripheralName: UILabel! - - public var centralManager: SILCentralManager!; - public var connectedPeripheral: CBPeripheral!; - - override func viewDidLoad() { - super.viewDidLoad() - viewModel = SILEnvironmentViewModel(centralManager: centralManager!, connectedPeripheral: connectedPeripheral!) - self.peripheralName?.text = viewModel?.checkPeripheralName() - } - - override func viewDidAppear(_ animated: Bool) { - self.navigationController?.interactivePopGestureRecognizer?.delegate = self - } - - override func viewWillDisappear(_ animated: Bool) { - viewModel?.viewWillDisappear() - } - - @IBAction func backButtonTapped() -> Void { - self.navigationController?.popViewController(animated: true) - } -} diff --git a/SiliconLabsApp/ViewControllers/Motion/SILMotionViewController.swift b/SiliconLabsApp/ViewControllers/Motion/SILMotionViewController.swift deleted file mode 100644 index a8af5f6e..00000000 --- a/SiliconLabsApp/ViewControllers/Motion/SILMotionViewController.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// MotionVC.swift -// BlueGecko -// -// Created by Anastazja Gradowska on 20/09/2021. -// Copyright © 2021 SiliconLabs. All rights reserved. -// - -import Foundation - - -class SILMotionViewController: UIViewController, UIGestureRecognizerDelegate { - @IBOutlet var navigationBar: UIView! - private var viewModel: SILMotionViewModel! - - @IBOutlet weak var peripheralName: UILabel? - - public var centralManager: SILCentralManager!; - public var connectedPeripheral: CBPeripheral!; - - override func viewDidLoad() { - super.viewDidLoad() - viewModel = SILMotionViewModel(centralManager: centralManager!, connectedPeripheral: connectedPeripheral!) - self.peripheralName?.text = viewModel?.checkPeripheralName() - } - - override func viewDidAppear(_ animated: Bool) { - self.navigationController?.interactivePopGestureRecognizer?.delegate = self - } - - override func viewWillDisappear(_ animated: Bool) { - viewModel.viewWillDisappear() - } - - @IBAction func backButtonTapped() -> Void { - self.navigationController?.popViewController(animated: true) - } -} diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestCharacteristic.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestCharacteristic.swift index 43afc009..19c2653a 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestCharacteristic.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestCharacteristic.swift @@ -195,4 +195,8 @@ extension SILRangeTestCharacteristic { return false } } + + func getServiceCharacteristicEnum() -> SILRangeTestServiceCharacteristics? { + return SILRangeTestCharacteristic.rangeTestServiceCharacteristics.first(where: { $1 == self.uuid.uuidString.lowercased() })?.key + } } diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestPeripheral.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestPeripheral.swift index 16570a1e..afd20f4c 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestPeripheral.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/Peripheral/SILRangeTestPeripheral.swift @@ -10,6 +10,7 @@ import UIKit //MARK: - Peripheral delegate protocol SILRangeTestPeripheralDelegate: class { + func didGetNotificationFromIsRunningCharacteristic() func didUpdate(connectionState: CBPeripheralState) func didUpdate(manufacturerData: SILRangeTestManufacturerData?) func bluetoothIsDisabled() @@ -23,7 +24,7 @@ class SILRangeTestPeripheral: NSObject { private typealias Characteristics = [CBUUID: [CBUUID: SILRangeTestCharacteristic]] private typealias ValueCallbacks = [CBUUID: [CBUUID: (SILRangeTestCharacteristic) -> Void]] - private var peripheral: CBPeripheral + var peripheral: CBPeripheral private let manager: SILCentralManager private var valuesCallbacks: ValueCallbacks = [:] private var characteristics: Characteristics = [:] @@ -67,7 +68,7 @@ class SILRangeTestPeripheral: NSObject { } func disconnect() { - manager.disconnectConnectedPeripheral() + manager.disconnect(from: peripheral) } private func prepareCharacteristics() { @@ -587,6 +588,12 @@ extension SILRangeTestPeripheral: CBPeripheralDelegate { return } + // when RX is started we get notification without changing characteristic value, so callback in self.valuesCallbacks won't be called + // We have to inform the delegate about getting this notification, because if in a short time device will disconnect it means the test's started. + if rtCharacteristic.getServiceCharacteristicEnum() == .isRunning { + delegate?.didGetNotificationFromIsRunningCharacteristic() + } + let containsNewValues = rtCharacteristic.update(withCharacteristic: characteristic) guard containsNewValues, let dataCallback = self.valuesCallbacks[serviceUUID]?[characteristicUUID] else { diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppContainerViewController.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppContainerViewController.swift index 0a2b0762..c488443c 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppContainerViewController.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppContainerViewController.swift @@ -7,46 +7,39 @@ // import UIKit +import SVProgressHUD +import CoreBluetooth struct SILSetTabDeviceName { let invoke: (String) -> Void } +protocol SILRangeTestBluetoothConnectionsHandler: class { + func addConnectedPeripheral(_ peripheral: CBPeripheral) + func deviceDidDisconnect() + func bluetoothIsDisabled() + var filter: DiscoveredPeripheralFilter { get } +} + class SILRangeTestAppContainerViewController: UIViewController, UITabBarControllerDelegate, UIGestureRecognizerDelegate { + @IBOutlet weak var navigationBar: UIView! @IBOutlet weak var tabSelection: UISegmentedControl! var tabController: UITabBarController! + var connectedPeripherals: [CBPeripheral] = [] override func viewDidLoad() { super.viewDidLoad() navigationBar.addShadow() navigationBar.superview?.bringSubviewToFront(navigationBar) - observeForBluetoothDisabledNotification() } override func viewDidAppear(_ animated: Bool) { self.navigationController?.interactivePopGestureRecognizer?.delegate = self } - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - NotificationCenter.default.removeObserver(self, name: NSNotification.Name.SILCentralManagerBluetoothDisabled, object: nil) - } - - func observeForBluetoothDisabledNotification() { - NotificationCenter.default.addObserver(self, selector: #selector(bluetoothIsDisabled(_:)), name: NSNotification.Name.SILCentralManagerBluetoothDisabled, object: nil) - } - - @objc func bluetoothIsDisabled(_ notification: Notification) { - let bluetoothDisabledAlert = SILBluetoothDisabledAlert.rangeTest - self.alertWithOKButton(title: bluetoothDisabledAlert.title, - message: bluetoothDisabledAlert.message, - completion: { [weak self] _ in self?.navigationController?.popToRootViewController(animated: true) - }) - } - @IBAction func backButtonTapped(_ sender: Any) { self.navigationController?.popViewController(animated: true) } @@ -60,6 +53,10 @@ class SILRangeTestAppContainerViewController: UIViewController, UITabBarControll tabController = (segue.destination as! UITabBarController) for i in tabController.viewControllers!.indices { + if let navigationController = tabController.viewControllers?[i] as? UINavigationController, let selectedDeviceVC = navigationController.viewControllers[0] as? SILRangeTestSelectDeviceViewController { + selectedDeviceVC.bluetoothConnectionsHandler = self + } + let context = SILSetTabDeviceName(invoke: { [weak self] (name: String) in self?.tabSelection.setTitle(name, forSegmentAt: i) }) @@ -76,5 +73,35 @@ class SILRangeTestAppContainerViewController: UIViewController, UITabBarControll } return false } +} + +extension SILRangeTestAppContainerViewController: SILRangeTestBluetoothConnectionsHandler { + var filter: DiscoveredPeripheralFilter { + return { discoveredPeripheral in + guard let discoveredPeripheral = discoveredPeripheral else { + return false + } + + return discoveredPeripheral.isRangeTest && !self.connectedPeripherals.contains(discoveredPeripheral.peripheral) + } + } + func bluetoothIsDisabled() { + let bluetoothDisabledAlert = SILBluetoothDisabledAlert.rangeTest + self.alertWithOKButton(title: bluetoothDisabledAlert.title, + message: bluetoothDisabledAlert.message, + completion: { [weak self] _ in self?.navigationController?.popToRootViewController(animated: true) + }) + } + + func deviceDidDisconnect() { + SVProgressHUD.showError(withStatus: "Device unexpectedly disconnected.") + self.navigationController?.popToRootViewController(animated: true) + } + + func addConnectedPeripheral(_ peripheral: CBPeripheral) { + if !connectedPeripherals.contains(peripheral) { + connectedPeripherals.append(peripheral) + } + } } diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewController.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewController.swift index 96eadf92..4d0b6f1b 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewController.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewController.swift @@ -10,6 +10,7 @@ import UIKit import ActionSheetPicker_3_0 import ChameleonFramework import Charts +import SVProgressHUD fileprivate struct Constants { static let sliderGrey = UIColor(red:0.85, green:0.84, blue:0.84, alpha:1.00) @@ -76,9 +77,7 @@ class SILRangeTestAppViewController: UIViewController { super.willMove(toParent: parent) if (parent == nil) { - viewModel.peripheral.clearCallbacks() - viewModel.peripheral.delegate = nil - viewModel.peripheral.disconnect() + self.viewModel.disconnect() UIApplication.shared.isIdleTimerDisabled = false; } @@ -88,11 +87,15 @@ class SILRangeTestAppViewController: UIViewController { super.viewWillAppear(animated) } + deinit { + self.viewModel.disconnect() + } + private func setTabDeviceName() { let setDeviceName = self.sil_useContext(type: SILSetTabDeviceName.self) setDeviceName?.invoke(viewModel.peripheral.discoveredPeripheral()?.advertisedLocalName ?? "Unknown") } - + private func prepareUI() { let isRxMode = viewModel.mode == .RX let isTxMode = viewModel.mode == .TX @@ -435,14 +438,6 @@ extension SILRangeTestAppViewController : SILRangeTestAppViewModelDelegate { updateLabel(per: per) } - - func bluetoothIsDisabled() { - let bluetoothDisabledAlert = SILBluetoothDisabledAlert.rangeTest - self.alertWithOKButton(title: bluetoothDisabledAlert.title, - message: bluetoothDisabledAlert.message, - completion: { [weak self] _ in self?.navigationController?.popToRootViewController(animated: true) - }) - } } // MARK: - Update label diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewModel.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewModel.swift index 73f1e67f..536bf450 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewModel.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestAppViewModel.swift @@ -24,8 +24,6 @@ protocol SILRangeTestAppViewModelDelegate: class { func updated(totalTx: Int) func updated(ma: Float) func updated(per: Float) - - func bluetoothIsDisabled() } @objcMembers @@ -55,6 +53,10 @@ class SILRangeTestAppViewModel : NSObject, SILRangeTestPeripheralDelegate { } } + private var waitingForDisconnectTimer: Timer? + private var shouldDisconnect = false + private weak var bluetoothConnectionsHandler: SILRangeTestBluetoothConnectionsHandler? + let peripheral: SILRangeTestPeripheral let mode: SILRangeTestMode let boardInfo: SILRangeTestBoardInfo @@ -68,6 +70,7 @@ class SILRangeTestAppViewModel : NSObject, SILRangeTestPeripheralDelegate { peripheral.setIsRunning(isTestStarted) if isTestStarted { + shouldDisconnect = mode == .RX startTest() } else { stopTest() @@ -100,15 +103,17 @@ class SILRangeTestAppViewModel : NSObject, SILRangeTestPeripheralDelegate { } } - init(withMode mode: SILRangeTestMode, peripheral: SILRangeTestPeripheral, andBoardInfo boardInfo: SILRangeTestBoardInfo) { + init(withMode mode: SILRangeTestMode, peripheral: SILRangeTestPeripheral, boardInfo: SILRangeTestBoardInfo, bluetoothConnectionsHandler: SILRangeTestBluetoothConnectionsHandler?) { self.mode = mode self.peripheral = peripheral self.boardInfo = boardInfo + self.bluetoothConnectionsHandler = bluetoothConnectionsHandler super.init() self.peripheral.delegate = self self.registerForPeripheralValuesUpdates() + self.bluetoothConnectionsHandler?.addConnectedPeripheral(self.peripheral.peripheral) } func getAllAvailableSettings() -> [SILRangeTestSetting] { @@ -222,12 +227,19 @@ class SILRangeTestAppViewModel : NSObject, SILRangeTestPeripheralDelegate { func didUpdate(connectionState: CBPeripheralState) { if connectionState == .connected { self.registerForPeripheralValuesUpdates() + return + } + if connectionState == .disconnected { + if shouldDisconnect { + isTestStarted = true + } else { + bluetoothConnectionsHandler?.deviceDidDisconnect() + } } } func didUpdate(manufacturerData: SILRangeTestManufacturerData?) { guard let manufData = manufacturerData else { - handleMissingManufacturerData() return } @@ -247,13 +259,26 @@ class SILRangeTestAppViewModel : NSObject, SILRangeTestPeripheralDelegate { } func bluetoothIsDisabled() { - delegate?.bluetoothIsDisabled() + bluetoothConnectionsHandler?.bluetoothIsDisabled() } - private func handleMissingManufacturerData() { - isTestStarted = false - peripheral.connect() - registerForPeripheralValuesUpdates() + func didGetNotificationFromIsRunningCharacteristic() { + if self.mode == .RX { + runWaitingForDisconnectTimer() + } + } + + func disconnect() { + peripheral.clearCallbacks() + peripheral.delegate = nil + peripheral.disconnect() + } + + private func runWaitingForDisconnectTimer() { + self.shouldDisconnect = true + self.waitingForDisconnectTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in + self.shouldDisconnect = false + } } private func startTest() { diff --git a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestSelectDeviceViewController.swift b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestSelectDeviceViewController.swift index cd883896..4afdd6c6 100644 --- a/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestSelectDeviceViewController.swift +++ b/SiliconLabsApp/ViewControllers/RangeTestApp/SILRangeTestSelectDeviceViewController.swift @@ -16,6 +16,7 @@ class SILRangeTestSelectDeviceViewController: UIViewController, SILDeviceSelecti private let centralManager = SILBrowserConnectionsViewModel.sharedInstance()!.centralManager! private var popoverController: WYPopoverController? + weak var bluetoothConnectionsHandler: SILRangeTestBluetoothConnectionsHandler? override func viewDidLoad() { super.viewDidLoad() @@ -37,9 +38,7 @@ class SILRangeTestSelectDeviceViewController: UIViewController, SILDeviceSelecti self.popoverController?.dismissPopover(animated: false) let viewModel = SILDeviceSelectionViewModel(appType: app) - viewModel?.filter = { discoveredPeripheral in - return discoveredPeripheral?.isRangeTest ?? false - } + viewModel?.filter = bluetoothConnectionsHandler?.filter let selectionViewController = SILDeviceSelectionViewController(deviceSelectionViewModel: viewModel!) @@ -78,7 +77,10 @@ class SILRangeTestSelectDeviceViewController: UIViewController, SILDeviceSelecti self.popoverController?.dismissPopover(animated: true) { let storyboard = UIStoryboard(name: "SILAppTypeRangeTest", bundle: nil) let viewController = storyboard.instantiateViewController(withIdentifier: "SILRangeTestAppViewController") as! SILRangeTestAppViewController - let viewModel = SILRangeTestAppViewModel(withMode: mode, peripheral: peripheral!, andBoardInfo: boardInfo!) + let viewModel = SILRangeTestAppViewModel(withMode: mode, + peripheral: peripheral!, + boardInfo: boardInfo!, + bluetoothConnectionsHandler: self.bluetoothConnectionsHandler) viewController.app = app; viewController.viewModel = viewModel; diff --git a/SiliconLabsApp/ViewModels/Environment/SILEnvironmentViewModel.swift b/SiliconLabsApp/ViewModels/Environment/SILEnvironmentViewModel.swift deleted file mode 100644 index d748b6fa..00000000 --- a/SiliconLabsApp/ViewModels/Environment/SILEnvironmentViewModel.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// SILEnvironmentViewModel.swift -// BlueGecko -// -// Created by Anastazja Gradowska on 21/09/2021. -// Copyright © 2021 SiliconLabs. All rights reserved. -// - -import Foundation - -class SILEnvironmentViewModel { - var centralManager: SILCentralManager - var connectedPeripheral: CBPeripheral - - var peripheralConnectionStatus: SILObservable = SILObservable(initialValue: true) - var bluetoothState: SILObservable = SILObservable(initialValue: true) - - init(centralManager: SILCentralManager, connectedPeripheral: CBPeripheral) { - self.centralManager = centralManager - self.connectedPeripheral = connectedPeripheral - } - - public func viewWillDisappear() { - NotificationCenter.default.removeObserver(self) - centralManager.disconnect(from: self.connectedPeripheral) - } - - @objc private func didDisconnectPeripheral(notification: Notification) { - peripheralConnectionStatus.value = false - } - - @objc private func bluetoothIsDisabled(notification: Notification) { - bluetoothState.value = false - } - - func checkPeripheralName() -> String { - return connectedPeripheral.name! - } -} - - diff --git a/SiliconLabsApp/ViewModels/Motion/SILMotionViewModel.swift b/SiliconLabsApp/ViewModels/Motion/SILMotionViewModel.swift deleted file mode 100644 index 659cdebb..00000000 --- a/SiliconLabsApp/ViewModels/Motion/SILMotionViewModel.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// SILMotionViewModel.swift -// BlueGecko -// -// Created by Anastazja Gradowska on 21/09/2021. -// Copyright © 2021 SiliconLabs. All rights reserved. -// - -import Foundation - -class SILMotionViewModel { - var centralManager: SILCentralManager - var connectedPeripheral: CBPeripheral - - var peripheralConnectionStatus: SILObservable = SILObservable(initialValue: true) - var bluetoothState: SILObservable = SILObservable(initialValue: true) - - init(centralManager: SILCentralManager, connectedPeripheral: CBPeripheral) { - self.centralManager = centralManager - self.connectedPeripheral = connectedPeripheral - } - - public func viewWillDisappear() { - NotificationCenter.default.removeObserver(self) - centralManager.disconnect(from: self.connectedPeripheral) - } - - @objc private func didDisconnectPeripheral(notification: Notification) { - peripheralConnectionStatus.value = false - } - - @objc private func bluetoothIsDisabled(notification: Notification) { - bluetoothState.value = false - } - - func checkPeripheralName() -> String { - return connectedPeripheral.name! - } -}