From 3d44c90d3caa1068997dd4838686df67befdeade Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 22 Sep 2019 11:05:22 +0200 Subject: [PATCH 01/76] Fix labelValue() (#414) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix for #409 * Improving test stability by setting UserDefaults for testing to default values Signed-off-by: Tim Müller-Seydlitz --- openHAB/OpenHABWidget.swift | 73 ++++++++++--------- openHABTestsSwift/OpenHABGeneralTests.swift | 8 ++ .../OpenHABUserDefaultsTests.swift | 18 ++++- openHABTestsSwift/OpenHABXMLParserTests.swift | 6 +- 4 files changed, 66 insertions(+), 39 deletions(-) diff --git a/openHAB/OpenHABWidget.swift b/openHAB/OpenHABWidget.swift index 2808bf3f8..536655690 100644 --- a/openHAB/OpenHABWidget.swift +++ b/openHAB/OpenHABWidget.swift @@ -48,28 +48,56 @@ class OpenHABWidget: NSObject, MKAnnotation { return array[0].trimmingCharacters(in: .whitespaces) } - // Text after "[" + // Text between square brackets var labelValue: String? { - let array = label.components(separatedBy: "[") - if array.count > 1 { - var characterSet = CharacterSet.whitespaces - characterSet.insert(charactersIn: "]") - return array[1].trimmingCharacters(in: characterSet) - } - return nil + + // Swift 5 raw strings + let regex = try? NSRegularExpression(pattern: #"\[(.*?)\]"#, options: []) + guard let match = regex?.firstMatch(in: label, options: [], range: NSRange(location: 0, length: (label as NSString).length)) else { return nil } + guard let range = Range(match.range(at: 1), in: label) else { return nil } + return String(label[range]) + } var coordinate: CLLocationCoordinate2D { return item?.stateAsLocation()?.coordinate ?? kCLLocationCoordinate2DInvalid } + func sendCommandDouble(_ command: Double) { + sendCommand(String(command)) + } + + func sendCommand(_ command: String?) { + guard let item = item else { + os_log("Command for Item = nil", log: .default, type: .info) + return + } + guard let sendCommand = sendCommand else { + os_log("sendCommand closure not set", log: .default, type: .info) + return + } + sendCommand(item, command) + } + + func mappingIndex(byCommand command: String?) -> Int? { + for mapping in mappings where mapping.command == command { + return (mappings as NSArray).index(of: mapping) + } + return nil + } + +} + +extension OpenHABWidget { + // This is an ugly initializer - init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABLinkedPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget] ) { + convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABLinkedPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget] ) { func toString (_ with: Double?) -> String { guard let double = with else { return "" } return String(format: "%.1f", double) } + self.init() self.widgetId = widgetId self.label = label self.type = type @@ -105,8 +133,8 @@ class OpenHABWidget: NSObject, MKAnnotation { self.step = abs(self.step) } - init(xml xmlElement: XMLElement) { - super.init() + convenience init(xml xmlElement: XMLElement) { + self.init() for child in xmlElement.children { switch child.tag { case "widgetId": widgetId = child.stringValue @@ -142,29 +170,6 @@ class OpenHABWidget: NSObject, MKAnnotation { } } } - - func sendCommandDouble(_ command: Double) { - sendCommand(String(command)) - } - - func sendCommand(_ command: String?) { - guard let item = item else { - os_log("Command for Item = nil", log: .default, type: .info) - return - } - guard let sendCommand = sendCommand else { - os_log("sendCommand closure not set", log: .default, type: .info) - return - } - sendCommand(item, command) - } - - func mappingIndex(byCommand command: String?) -> Int? { - for mapping in mappings where mapping.command == command { - return (mappings as NSArray).index(of: mapping) - } - return nil - } } extension OpenHABWidget { diff --git a/openHABTestsSwift/OpenHABGeneralTests.swift b/openHABTestsSwift/OpenHABGeneralTests.swift index 116474a5b..c84d09254 100644 --- a/openHABTestsSwift/OpenHABGeneralTests.swift +++ b/openHABTestsSwift/OpenHABGeneralTests.swift @@ -53,4 +53,12 @@ class OpenHABGeneralTests: XCTestCase { iconType: .svg ).url XCTAssertEqual(urlc, URL(string: "http://192.169.2.1/icon/switch?state=OFF&format=SVG"), "Check endpoint creation") } + + func testLabelVale() { + let widget = OpenHABWidget() + widget.label = "llldl [llsl]" + XCTAssertEqual(widget.labelValue, "llsl") + widget.label = "llllsl[kkks] llls" + XCTAssertEqual(widget.labelValue, "kkks") + } } diff --git a/openHABTestsSwift/OpenHABUserDefaultsTests.swift b/openHABTestsSwift/OpenHABUserDefaultsTests.swift index 184954229..fa470666b 100644 --- a/openHABTestsSwift/OpenHABUserDefaultsTests.swift +++ b/openHABTestsSwift/OpenHABUserDefaultsTests.swift @@ -10,15 +10,29 @@ import XCTest class OpenHABUserDefaultsTests: XCTestCase { + override func setUp() { + super.setUp() + let defaultsName = Bundle.main.bundleIdentifier! + UserDefaults.standard.removePersistentDomain(forName: defaultsName) + + Preferences.username = Preferences.username + Preferences.localUrl = Preferences.localUrl + Preferences.remoteUrl = Preferences.remoteUrl + Preferences.password = Preferences.password + Preferences.ignoreSSL = Preferences.ignoreSSL + Preferences.demomode = Preferences.demomode + Preferences.idleOff = Preferences.idleOff + Preferences.iconType = Preferences.iconType + Preferences.defaultSitemap = Preferences.defaultSitemap + } + // Testing the consistency between properties of Preferences and the corresponding entry in UserDefaults func testConsistency() { XCTAssertEqual(Preferences.username, UserDefaults.standard.string(forKey: "username")) XCTAssertNotEqual(Preferences.username, UserDefaults.standard.string(forKey: "usern")) - XCTAssertEqual(Preferences.localUrl, UserDefaults.standard.string(forKey: "localUrl")) XCTAssertEqual(Preferences.remoteUrl, UserDefaults.standard.string(forKey: "remoteUrl")) - XCTAssertEqual(Preferences.username, UserDefaults.standard.string(forKey: "username")) XCTAssertEqual(Preferences.password, UserDefaults.standard.string(forKey: "password")) XCTAssertEqual(Preferences.ignoreSSL, UserDefaults.standard.bool(forKey: "ignoreSSL")) // XCTAssertEqual(Preferences.sitemapName, UserDefaults.standard.string(forKey: "sitemapName")) diff --git a/openHABTestsSwift/OpenHABXMLParserTests.swift b/openHABTestsSwift/OpenHABXMLParserTests.swift index e287f2088..60acc1087 100644 --- a/openHABTestsSwift/OpenHABXMLParserTests.swift +++ b/openHABTestsSwift/OpenHABXMLParserTests.swift @@ -48,7 +48,7 @@ class OpenHABXMLParserTests: XCTestCase { } } - func testFuzisingleXMLWidgetDecoder() { + func testFuziSingleXMLWidgetDecoder() { var widget: OpenHABWidget do { @@ -64,7 +64,7 @@ class OpenHABXMLParserTests: XCTestCase { } } - func testnestedXMLWidgetDecoder() { + func testNestedXMLWidgetDecoder() { var widget: OpenHABWidget do { @@ -80,7 +80,7 @@ class OpenHABXMLParserTests: XCTestCase { } } - func testshortUrlXMLWidgetDecoder() { + func testShortUrlXMLWidgetDecoder() { var widget: OpenHABWidget do { From cc5ede155b246e750915ff400af8e0fa35e18013 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 22 Sep 2019 22:06:51 +0200 Subject: [PATCH 02/76] Migrate sidemenu to version compatible with iOS 13 (#415) * dark mode Support (#408 adjustment to storyboard and hard-coded colors to support dark mode in iOS 13 Closes #372 * Fix for #409 * As required by iOS13 migrate to SideMenu 6.x: Migration to new syntax for parameters, renamed DrawerTableType enum cases, setting the defaultSitemap to sitemap selected in side menu. - Dirty but working for the moment Signed-off-by: Michel Mohrmann * Improving test stability by setting UserDefaults for testing to default values --- Podfile | 2 +- Podfile.lock | 48 +-- openHAB.xcodeproj/project.pbxproj | 12 +- openHAB/Base.lproj/Main.storyboard | 298 +++++++++--------- openHAB/ColorPickerViewController.swift | 8 + openHAB/GenericUITableViewCell.swift | 12 +- .../OpenHABDrawerTableViewController.swift | 17 +- .../OpenHABNotificationsViewController.swift | 4 +- openHAB/OpenHABSettingsViewController.swift | 2 +- openHAB/OpenHABViewController.swift | 38 ++- openHAB/openHAB-Info.plist | 4 +- openHABTestsSwift/Info.plist | 4 +- openHABUITests/Info.plist | 4 +- openHABWatch Extension/Info.plist | 4 +- openHABWatch/Info.plist | 4 +- 15 files changed, 243 insertions(+), 218 deletions(-) diff --git a/Podfile b/Podfile index 71726a8bc..00e089790 100644 --- a/Podfile +++ b/Podfile @@ -9,7 +9,7 @@ target 'openHAB' do pod 'Fabric', '~> 1.7.2' pod 'Crashlytics', '~> 3.9.3' pod 'SwiftMessages' - pod 'SideMenu', '~> 5.0' + pod 'SideMenu' pod 'FlexColorPicker' pod 'DynamicButton', '~> 6.2' pod 'Alamofire', '~> 4.0' diff --git a/Podfile.lock b/Podfile.lock index 0fed0f1c3..1ddd38586 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -7,11 +7,11 @@ PODS: - Fabric (~> 1.7.2) - DynamicButton (6.2.0) - Fabric (1.7.13) - - Firebase/Core (6.8.0): + - Firebase/Core (6.8.1): - Firebase/CoreOnly - FirebaseAnalytics (= 6.1.1) - - Firebase/CoreOnly (6.8.0): - - FirebaseCore (= 6.2.2) + - Firebase/CoreOnly (6.8.1): + - FirebaseCore (= 6.2.3) - FirebaseAnalytics (6.1.1): - FirebaseCore (~> 6.2) - FirebaseInstanceID (~> 4.2) @@ -21,7 +21,7 @@ PODS: - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 0.3) - - FirebaseCore (6.2.2): + - FirebaseCore (6.2.3): - FirebaseCoreDiagnostics (~> 1.0) - FirebaseCoreDiagnosticsInterop (~> 1.0) - GoogleUtilities/Environment (~> 6.2) @@ -32,7 +32,7 @@ PODS: - GoogleUtilities/Environment (~> 6.2) - GoogleUtilities/Logger (~> 6.2) - FirebaseCoreDiagnosticsInterop (1.0.0) - - FirebaseInstanceID (4.2.4): + - FirebaseInstanceID (4.2.5): - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) @@ -45,26 +45,26 @@ PODS: - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 0.3) - GoogleDataTransport (1.2.0) - - GoogleDataTransportCCTSupport (1.0.3): + - GoogleDataTransportCCTSupport (1.0.4): - GoogleDataTransport (~> 1.2) - nanopb - - GoogleUtilities/AppDelegateSwizzler (6.2.5): + - GoogleUtilities/AppDelegateSwizzler (6.3.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.2.5) - - GoogleUtilities/Logger (6.2.5): + - GoogleUtilities/Environment (6.3.0) + - GoogleUtilities/Logger (6.3.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.2.5): + - GoogleUtilities/MethodSwizzler (6.3.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.2.5): + - GoogleUtilities/Network (6.3.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.2.5)" - - GoogleUtilities/Reachability (6.2.5): + - "GoogleUtilities/NSData+zlib (6.3.0)" + - GoogleUtilities/Reachability (6.3.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.2.5): + - GoogleUtilities/UserDefaults (6.3.0): - GoogleUtilities/Logger - Kingfisher (5.7.1) - nanopb (0.3.901): @@ -72,7 +72,7 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - - SideMenu (5.0.3) + - SideMenu (6.3.1) - SVGKit (2.1.1): - CocoaLumberjack (~> 3.0) - SwiftMessages (7.0.0): @@ -88,9 +88,9 @@ DEPENDENCIES: - FlexColorPicker - Fuzi (~> 3.1) - Kingfisher (~> 5.0) - - SideMenu (~> 5.0) + - SideMenu - SVGKit - - SwiftMessages + - SwiftMessages (< 7.0.1) SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -123,24 +123,24 @@ SPEC CHECKSUMS: Crashlytics: dbb07d01876c171c5ccbdf7826410380189e452c DynamicButton: 99858ce823ceed7263a4eed43bd3870e72723cb2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: c35912a5c160193dc423f260dac3f167a1a795ab + Firebase: 9cbe4e5b5eaafa05dc932be58b7c8c3820d71e88 FirebaseAnalytics: 843c7f64a8f9c79f0d03281197ebe7bb1d58d477 - FirebaseCore: 12422a2a2b79ed161b06ccad1edfe650de7a4b34 + FirebaseCore: e9d9bd1dae61c1e82bc1e0e617a9d832392086a0 FirebaseCoreDiagnostics: 4c04ae09d0ab027c30179828c6bb47764df1bd13 FirebaseCoreDiagnosticsInterop: 6829da2b8d1fc795ff1bd99df751d3788035d2cb - FirebaseInstanceID: 88932a31aba5a56cfd3a7541706436c71f7f4598 + FirebaseInstanceID: 550df9be1f99f751d8fcde3ac342a1e21a0e6c42 FlexColorPicker: 2c6fe41cb33a650d5934fad75ab0e25df4b5af2f Fuzi: bcc5694488dd6e672e126cbf3c5471d7a79506d1 GoogleAppMeasurement: 86a82f0e1f20b8eedf8e20326530138fd71409de GoogleDataTransport: 8f9897b8e073687f24ca8d3c3a8013dec7d2d1cc - GoogleDataTransportCCTSupport: 51134d81fca795c60cc247d1cb6af63c3d67b8d8 - GoogleUtilities: e7dc37039b19df7fe543479d3e4a02ac8d11bb69 + GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e + GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51 Kingfisher: 176d377ad339113c99ad4980cbae687f807e20fe nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - SideMenu: 1dcaabce84538c53325c287f7fe62999379a641c + SideMenu: 8c67753662a891321bb646b03fca9f132ae5433a SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac SwiftMessages: a952f7a9103d9aeab93730a2861d2d8fcdd8758f -PODFILE CHECKSUM: fe7b725b7b433c359748dc57fe5eb3cc76993e92 +PODFILE CHECKSUM: 062bcf98c6f3cb201c0b414472780f74c5e84314 COCOAPODS: 1.7.1 diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index b50aa1cc5..dd8124c3a 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -620,14 +620,14 @@ DF4B83FD18857FA100F34902 /* UI */ = { isa = PBXGroup; children = ( - A07EF79F2230C0A20040919F /* OpenHABClientCertificatesViewController.swift */, + DFB2624318830A3600D3244D /* OpenHABViewController.swift */, + DFDEE3FC18831099008B26AC /* OpenHABSettingsViewController.swift */, + DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */, DFDF45331934699B00A6E581 /* OpenHABInfoViewController.swift */, DFDF452E1932032B00A6E581 /* OpenHABLegalViewController.swift */, DF06F1F518FE7A160011E7B9 /* OpenHABSelectionTableViewController.swift */, DAEAA89621DF8D8C00267EA3 /* OpenHABSelectionTableViewControllerDelegate.swift */, - DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */, - DFDEE3FC18831099008B26AC /* OpenHABSettingsViewController.swift */, - DFB2624318830A3600D3244D /* OpenHABViewController.swift */, + A07EF79F2230C0A20040919F /* OpenHABClientCertificatesViewController.swift */, DF4B84101886DA9900F34902 /* Widgets */, DF4A02291CF3157B006C3456 /* Drawer */, DFFD8FCE18EDBD30003B502A /* Util */, @@ -1746,7 +1746,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "openHAB/openHAB-Prefix.pch"; @@ -1787,7 +1787,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "openHAB/openHAB-Prefix.pch"; diff --git a/openHAB/Base.lproj/Main.storyboard b/openHAB/Base.lproj/Main.storyboard index 5acdd18b9..1f60ae6b7 100644 --- a/openHAB/Base.lproj/Main.storyboard +++ b/openHAB/Base.lproj/Main.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -23,17 +21,17 @@ - + - + - + - - + - + @@ -86,23 +83,23 @@ - + - + - + - + - + @@ -256,10 +253,10 @@ - + - + @@ -277,15 +274,15 @@ @@ -309,21 +306,21 @@ - + - + @@ -344,14 +341,14 @@ - + - + - + @@ -362,14 +359,14 @@ @@ -393,10 +390,10 @@ - + - + @@ -476,14 +473,14 @@ - + - + - + @@ -498,14 +495,14 @@ - + - + - + @@ -523,10 +520,10 @@ - + - + @@ -534,14 +531,14 @@ - + - + - + @@ -597,24 +594,24 @@ - + - + - + - + @@ -635,19 +632,19 @@ - + - + - + @@ -670,19 +667,19 @@ - + - + - + @@ -705,19 +702,19 @@ - + - + - + @@ -740,19 +737,19 @@ - + - + - + @@ -779,19 +776,19 @@ - + - + - + @@ -812,10 +809,10 @@ - + - + - + - + - + @@ -870,10 +867,10 @@ - + - + - + - + - + @@ -919,14 +916,14 @@ - + - + @@ -944,14 +941,14 @@ - + - + @@ -967,14 +964,14 @@ - + - + @@ -1023,25 +1020,25 @@ - + - + @@ -1079,11 +1076,16 @@ - + - + + + + + + @@ -1097,31 +1099,31 @@ - + - + - + - + @@ -1133,24 +1135,24 @@ - + - + @@ -1162,24 +1164,24 @@ - + - + @@ -1191,24 +1193,24 @@ - + - + @@ -1244,15 +1246,15 @@ - + - + - + @@ -1278,7 +1280,6 @@ - @@ -1293,13 +1294,13 @@ - + - + - + @@ -1324,17 +1325,16 @@ - + - - + + - @@ -1357,7 +1357,6 @@ - @@ -1373,21 +1372,20 @@ - + - + - + - @@ -1396,7 +1394,7 @@ @@ -1433,6 +1431,6 @@ - + diff --git a/openHAB/ColorPickerViewController.swift b/openHAB/ColorPickerViewController.swift index 5850c1feb..963ea32bd 100644 --- a/openHAB/ColorPickerViewController.swift +++ b/openHAB/ColorPickerViewController.swift @@ -30,6 +30,14 @@ class ColorPickerViewController: DefaultColorPickerViewController { delegate = self + if #available(iOS 13.0, *) { + // if nothing is set DefaultColorPickerViewController will fall back to .white + // if we set this manually DefaultColorPickerViewController will go with that + self.view.backgroundColor = .systemBackground + } else { + // do nothing - DefaultColorPickerViewController will handle this + } + super.viewDidLoad() } diff --git a/openHAB/GenericUITableViewCell.swift b/openHAB/GenericUITableViewCell.swift index 742e36cc6..3e4397b8f 100644 --- a/openHAB/GenericUITableViewCell.swift +++ b/openHAB/GenericUITableViewCell.swift @@ -40,14 +40,22 @@ class GenericUITableViewCell: UITableViewCell { customTextLabel?.textColor = color } } else { - customTextLabel?.textColor = UIColor.black + if #available(iOS 13.0, *) { + customTextLabel?.textColor = UIColor.label + } else { + customTextLabel?.textColor = UIColor.black + } } if _widget.valuecolor != "" { if let color = color(fromHexString: self.widget?.valuecolor) { customDetailTextLabel?.textColor = color } } else { - customDetailTextLabel?.textColor = UIColor.lightGray + if #available(iOS 13.0, *) { + customDetailTextLabel?.textColor = UIColor.secondaryLabel + } else { + customDetailTextLabel?.textColor = UIColor.lightGray + } } } } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index 92e7b9741..e7610ebde 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -56,8 +56,8 @@ func deriveSitemaps(_ response: Data?, version: Int?) -> [OpenHABSitemap] { } enum DrawerTableType { - case with - case without + case withStandardMenuEntries + case withoutStandardMenuEntries } class OpenHABDrawerTableViewController: UITableViewController { @@ -78,8 +78,8 @@ class OpenHABDrawerTableViewController: UITableViewController { } init(drawerTableType: DrawerTableType?) { - self.drawerTableType = drawerTableType super.init(nibName: nil, bundle: nil) + self.drawerTableType = drawerTableType } required init?(coder aDecoder: NSCoder) { @@ -92,7 +92,7 @@ class OpenHABDrawerTableViewController: UITableViewController { drawerItems = [] sitemaps = [] loadSettings() - if drawerTableType == .with { + if drawerTableType == .withStandardMenuEntries { setStandardDrawerItems() } os_log("OpenHABDrawerTableViewController did load", log: .viewCycle, type: .info) @@ -117,7 +117,7 @@ class OpenHABDrawerTableViewController: UITableViewController { // Sort the sitemaps alphabetically. self.sitemaps.sort { $0.name < $1.name } self.drawerItems.removeAll() - if self.drawerTableType == .with { + if self.drawerTableType == .withStandardMenuEntries { self.setStandardDrawerItems() } self.tableView.reloadData() @@ -125,7 +125,7 @@ class OpenHABDrawerTableViewController: UITableViewController { UIApplication.shared.isNetworkActivityIndicatorVisible = false os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) self.drawerItems.removeAll() - if self.drawerTableType == .with { + if self.drawerTableType == .withStandardMenuEntries { self.setStandardDrawerItems() } self.tableView.reloadData() @@ -213,12 +213,11 @@ class OpenHABDrawerTableViewController: UITableViewController { Preferences.defaultSitemap = sitemap.name appData?.rootViewController?.pageUrl = "" switch drawerTableType { - case .with?: + case .withStandardMenuEntries?: dismiss(animated: true) { self.delegate?.modalDismissed(to: .root) } - case .without?: - appData?.rootViewController?.pageUrl = "" + case .withoutStandardMenuEntries?: navigationController?.popToRootViewController(animated: true) case .none: break diff --git a/openHAB/OpenHABNotificationsViewController.swift b/openHAB/OpenHABNotificationsViewController.swift index d5bfaa8e5..a44435e46 100644 --- a/openHAB/OpenHABNotificationsViewController.swift +++ b/openHAB/OpenHABNotificationsViewController.swift @@ -13,7 +13,7 @@ import os.log import SideMenu import UIKit -class OpenHABNotificationsViewController: UITableViewController, UISideMenuNavigationControllerDelegate { +class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigationControllerDelegate { static let tableViewCellIdentifier = "NotificationCell" var notifications: NSMutableArray = [] @@ -88,7 +88,7 @@ class OpenHABNotificationsViewController: UITableViewController, UISideMenuNavig @objc func rightDrawerButtonPress(_ sender: Any?) { - present(SideMenuManager.default.menuRightNavigationController!, animated: true, completion: nil) + present(SideMenuManager.default.rightMenuNavigationController!, animated: true, completion: nil) } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { diff --git a/openHAB/OpenHABSettingsViewController.swift b/openHAB/OpenHABSettingsViewController.swift index d4628b7c6..9c96ba334 100644 --- a/openHAB/OpenHABSettingsViewController.swift +++ b/openHAB/OpenHABSettingsViewController.swift @@ -136,7 +136,7 @@ class OpenHABSettingsViewController: UITableViewController, UITextFieldDelegate if segue.identifier == "showSelectSitemap" { os_log("OpenHABSettingsViewController showSelectSitemap", log: .viewCycle, type: .info) let dest = segue.destination as! OpenHABDrawerTableViewController - dest.drawerTableType = .without + dest.drawerTableType = .withoutStandardMenuEntries dest.openHABRootUrl = appData?.openHABRootUrl ?? "" dest.delegate = appData?.rootViewController updateSettings() diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 2daa81422..8ee074434 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -118,7 +118,7 @@ class OpenHABViewController: UIViewController { super.viewDidLoad() os_log("OpenHABViewController viewDidLoad", log: .default, type: .info) - pageNetworkStatus = nil //NetworkStatus(rawValue: -1) + pageNetworkStatus = nil sitemaps = [] widgetTableView.tableFooterView = UIView() NotificationCenter.default.addObserver(self, selector: #selector(OpenHABViewController.didEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil) @@ -263,14 +263,20 @@ class OpenHABViewController: UIViewController { fileprivate func setupSideMenu() { // Define the menus - SideMenuManager.default.menuRightNavigationController = storyboard!.instantiateViewController(withIdentifier: "RightMenuNavigationController") as? UISideMenuNavigationController + SideMenuManager.default.rightMenuNavigationController = storyboard!.instantiateViewController(withIdentifier: "RightMenuNavigationController") as? SideMenuNavigationController // Enable gestures. The left and/or right menus must be set up above for these to work. // Note that these continue to work on the Navigation Controller independent of the View Controller it displays! - SideMenuManager.default.menuAddPanGestureToPresent(toView: self.navigationController!.navigationBar) - SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController!.view) + SideMenuManager.default.addPanGestureToPresent(toView: self.navigationController!.navigationBar) + SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.navigationController!.view) - SideMenuManager.default.menuFadeStatusBar = false + let presentationStyle: SideMenuPresentationStyle = .menuSlideIn + presentationStyle.presentingEndAlpha = 0 + var settings = SideMenuSettings() + settings.presentationStyle = presentationStyle + settings.statusBarEndAlpha = 0 + + SideMenuManager.default.rightMenuNavigationController?.settings = settings } func configureTableView() { @@ -353,15 +359,15 @@ class OpenHABViewController: UIViewController { switch segue.identifier { case "showSelectionView": os_log("Selection seague", log: .viewCycle, type: .info) case "sideMenu": - let navigation = segue.destination as? UINavigationController + let navigation = segue.destination as? SideMenuNavigationController let drawer = navigation?.viewControllers[0] as? OpenHABDrawerTableViewController drawer?.openHABRootUrl = openHABRootUrl drawer?.delegate = self - drawer?.drawerTableType = .with + drawer?.drawerTableType = .withStandardMenuEntries case "showSelectSitemap": let dest = segue.destination as! OpenHABDrawerTableViewController dest.openHABRootUrl = openHABRootUrl - dest.drawerTableType = .without + dest.drawerTableType = .withoutStandardMenuEntries dest.delegate = self default: break } @@ -647,7 +653,7 @@ class OpenHABViewController: UIViewController { } } - func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool) { + func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool) { self.hamburgerButton.setStyle(.hamburger, animated: animated) } @@ -841,6 +847,8 @@ extension OpenHABViewController: ModalHandler { switch to { case .root: navigationController?.popToRootViewController(animated: true) + defaultSitemap = Preferences.defaultSitemap + selectSitemap() case .settings: if let newViewController = storyboard?.instantiateViewController(withIdentifier: "OpenHABSettingsViewController") as? OpenHABSettingsViewController { navigationController?.pushViewController(newViewController, animated: true) @@ -858,8 +866,8 @@ extension OpenHABViewController: ModalHandler { } // MARK: - UISideMenuNavigationControllerDelegate -extension OpenHABViewController: UISideMenuNavigationControllerDelegate { - func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool) { +extension OpenHABViewController: SideMenuNavigationControllerDelegate { + func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) { self.hamburgerButton.setStyle(.arrowRight, animated: animated) guard let drawer = menu.viewControllers.first as? OpenHABDrawerTableViewController, @@ -869,7 +877,7 @@ extension OpenHABViewController: UISideMenuNavigationControllerDelegate { } drawer.openHABRootUrl = openHABRootUrl drawer.delegate = self - drawer.drawerTableType = .with + drawer.drawerTableType = .withStandardMenuEntries } } @@ -994,7 +1002,11 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { if cell is FrameUITableViewCell { cell.backgroundColor = UIColor.groupTableViewBackground } else { - cell.backgroundColor = UIColor.white + if #available(iOS 13.0, *) { + cell.backgroundColor = UIColor.systemBackground + } else { + cell.backgroundColor = UIColor.white + } } if let cell = cell as? GenericUITableViewCell { diff --git a/openHAB/openHAB-Info.plist b/openHAB/openHAB-Info.plist index cd32cd95a..7797ff915 100644 --- a/openHAB/openHAB-Info.plist +++ b/openHAB/openHAB-Info.plist @@ -32,7 +32,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.1.32 + 2.1.33 CFBundleSignature ???? CFBundleURLTypes @@ -47,7 +47,7 @@ CFBundleVersion - 64 + 65 ITSAppUsesNonExemptEncryption LSApplicationCategoryType diff --git a/openHABTestsSwift/Info.plist b/openHABTestsSwift/Info.plist index 0b5c363a1..f4fd15cbf 100644 --- a/openHABTestsSwift/Info.plist +++ b/openHABTestsSwift/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.1.32 + 2.1.33 CFBundleVersion - 64 + 65 diff --git a/openHABUITests/Info.plist b/openHABUITests/Info.plist index 0b5c363a1..f4fd15cbf 100644 --- a/openHABUITests/Info.plist +++ b/openHABUITests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.1.32 + 2.1.33 CFBundleVersion - 64 + 65 diff --git a/openHABWatch Extension/Info.plist b/openHABWatch Extension/Info.plist index 8d00f4e57..71460aa2d 100644 --- a/openHABWatch Extension/Info.plist +++ b/openHABWatch Extension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 2.1.32 + 2.1.33 CFBundleVersion - 64 + 65 CLKComplicationPrincipalClass ComplicationController CLKComplicationSupportedFamilies diff --git a/openHABWatch/Info.plist b/openHABWatch/Info.plist index 9ecca486e..6b0faa926 100644 --- a/openHABWatch/Info.plist +++ b/openHABWatch/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.1.32 + 2.1.33 CFBundleVersion - 64 + 65 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait From 90e66c7b8e883c525cf39c8899337e8da11d9a42 Mon Sep 17 00:00:00 2001 From: weak Date: Mon, 23 Sep 2019 17:39:08 +0200 Subject: [PATCH 03/76] migrate swiftlint to cocoapods and add swiftformat Signed-off-by: weak --- .swiftformat | 42 ++++++++++++++++++++++++++++++++++++++++++ Podfile | 2 ++ Podfile.lock | 14 +++++++++++--- 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 .swiftformat diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 000000000..313839b5e --- /dev/null +++ b/.swiftformat @@ -0,0 +1,42 @@ +# file options +--swiftversion 5.0 +--exclude Pods +--symlinks ignore + +# disabled rules +--disable specifiers # see https://github.com/nicklockwood/SwiftFormat/issues/364 + +# format options +--allman false +--binarygrouping none +--closingparen same-line +--commas inline +--conflictmarkers reject +--decimalgrouping none +--elseposition same-line +--empty void +--exponentcase lowercase +--exponentgrouping disabled +--fractiongrouping disabled +--fragment false +--header ignore +--hexgrouping none +--hexliteralcase lowercase +--ifdef no-indent +--importgrouping alphabetized +--indent 4 +--indentcase false +--linebreaks lf +--octalgrouping none +--operatorfunc space +--patternlet hoist +--ranges spaced +--self remove +--selfrequired +--semicolons inline +--stripunusedargs closure-only +--trailingclosures +--trimwhitespace always +--wraparguments after-first +--wrapcollections after-first +--xcodeindentation disabled diff --git a/Podfile b/Podfile index 00e089790..e89a3261b 100644 --- a/Podfile +++ b/Podfile @@ -4,6 +4,8 @@ platform :ios, '11.0' use_frameworks! target 'openHAB' do + pod 'SwiftFormat/CLI' + pod 'SwiftLint' pod 'SVGKit' pod 'Firebase/Core' pod 'Fabric', '~> 1.7.2' diff --git a/Podfile.lock b/Podfile.lock index 1ddd38586..dc0ec3016 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -75,6 +75,8 @@ PODS: - SideMenu (6.3.1) - SVGKit (2.1.1): - CocoaLumberjack (~> 3.0) + - SwiftFormat/CLI (0.40.12) + - SwiftLint (0.35.0) - SwiftMessages (7.0.0): - SwiftMessages/App (= 7.0.0) - SwiftMessages/App (7.0.0) @@ -90,7 +92,9 @@ DEPENDENCIES: - Kingfisher (~> 5.0) - SideMenu - SVGKit - - SwiftMessages (< 7.0.1) + - SwiftFormat/CLI + - SwiftLint + - SwiftMessages SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -115,6 +119,8 @@ SPEC REPOS: - nanopb - SideMenu - SVGKit + - SwiftFormat + - SwiftLint - SwiftMessages SPEC CHECKSUMS: @@ -139,8 +145,10 @@ SPEC CHECKSUMS: nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 SideMenu: 8c67753662a891321bb646b03fca9f132ae5433a SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac + SwiftFormat: 73667bbb741386b0febf0bd1a1b8c502aa9d1c98 + SwiftLint: 5553187048b900c91aa03552807681bb6b027846 SwiftMessages: a952f7a9103d9aeab93730a2861d2d8fcdd8758f -PODFILE CHECKSUM: 062bcf98c6f3cb201c0b414472780f74c5e84314 +PODFILE CHECKSUM: 7992aabfa3cc345bf07a1ead0bc7074376d15369 -COCOAPODS: 1.7.1 +COCOAPODS: 1.7.5 From 5c709dd4e29e1c52b4c8646343ab6e234c351e62 Mon Sep 17 00:00:00 2001 From: weak Date: Mon, 23 Sep 2019 17:39:34 +0200 Subject: [PATCH 04/76] add rule 'private_outlet' to swiftlint config Signed-off-by: weak --- .swiftlint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.swiftlint.yml b/.swiftlint.yml index 3ae3dcdc3..84e57323e 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -14,6 +14,7 @@ opt_in_rules: - reduce_boolean - file_types_order - type_contents_order + - private_outlet disabled_rules: # rule identifiers to exclude from running - force_cast - todo From b6d98758440614b5ff38aadcf75212d12277e9c7 Mon Sep 17 00:00:00 2001 From: weak Date: Mon, 23 Sep 2019 17:39:59 +0200 Subject: [PATCH 05/76] swiftformat and fix swiftlint warnings Signed-off-by: weak --- fastlane/SnapshotHelper.swift | 99 ++- openHAB.xcodeproj/project.pbxproj | 2 +- openHAB/AppDelegate.swift | 26 +- openHAB/ClientCertificateManager.swift | 52 +- openHAB/Collection+SafeAccess.swift | 2 +- openHAB/ColorPickerUITableViewCell.swift | 13 +- openHAB/ColorPickerViewController.swift | 2 +- openHAB/ColorUtil.swift | 16 +- openHAB/DrawerUITableViewCell.swift | 7 +- openHAB/DynamicButtonStyleBell.swift | 1 - openHAB/DynamicButtonStyleGear.swift | 3 +- openHAB/Endpoint.swift | 124 ++-- openHAB/FrameUITableViewCell.swift | 4 +- openHAB/GenericUITableViewCell.swift | 11 +- openHAB/MapViewTableViewCell.swift | 5 +- openHAB/NSData+HexString.swift | 1 - openHAB/NSObjectExtension.swift | 3 - openHAB/NetworkConnection.swift | 36 +- openHAB/NewImageTableViewCell.swift | 3 +- openHAB/NewImageUITableViewCell.swift | 23 +- openHAB/NotificationTableViewCell.swift | 6 +- openHAB/OpenHABAccessTokenAdapter.swift | 2 - ...nHABClientCertificatesViewController.swift | 2 +- .../OpenHABDrawerTableViewController.swift | 17 +- openHAB/OpenHABInfoViewController.swift | 8 +- openHAB/OpenHABItem.swift | 6 +- openHAB/OpenHABLegalViewController.swift | 2 +- openHAB/OpenHABNotification.swift | 2 +- .../OpenHABNotificationsViewController.swift | 13 +- ...onsViewControllerTableViewController.swift | 5 +- ...OpenHABSDWebImageDownloaderOperation.swift | 44 -- .../OpenHABSelectionTableViewController.swift | 2 +- openHAB/OpenHABSettingsViewController.swift | 34 +- openHAB/OpenHABSitemap.swift | 15 +- openHAB/OpenHABSitemapPage.swift | 28 +- openHAB/OpenHABTracker.swift | 14 +- openHAB/OpenHABViewController.swift | 148 +++-- openHAB/OpenHABWidget.swift | 23 +- openHAB/PlayerView.swift | 1 - openHAB/Reachability+URL.swift | 2 +- openHAB/Reachability.swift | 32 +- openHAB/ReusableView.swift | 8 +- openHAB/RollershutterUITableViewCell.swift | 18 +- openHAB/ScaleAspectFitImageView.swift | 26 +- openHAB/ScaledHeightUIImageView.swift | 1 - openHAB/SegmentedUITableViewCell.swift | 11 +- openHAB/SelectionUITableViewCell.swift | 1 - openHAB/ServerCertificateManager.swift | 18 +- openHAB/SetpointUITableViewCell.swift | 8 +- openHAB/SliderUITableViewCell.swift | 19 +- openHAB/StringExtension.swift | 3 +- openHAB/SwitchUITableViewCell.swift | 15 +- openHAB/UIAlertView+Block.swift | 2 +- openHAB/UICircleButton.swift | 2 +- openHAB/UITableView.swift | 12 +- openHAB/VideoUITableViewCell.swift | 42 +- openHAB/WatchMessageService.swift | 13 +- openHAB/WatchService.swift | 4 - openHAB/WebUITableViewCell.swift | 2 +- openHABTestsSwift/MockURLProtocol.swift | 8 +- openHABTestsSwift/OpenHABGeneralTests.swift | 10 +- .../OpenHABJSONParserTests.swift | 567 +++++++++--------- .../OpenHABUserDefaultsTests.swift | 4 +- openHABTestsSwift/OpenHABWatchTests.swift | 382 ++++++------ openHABTestsSwift/OpenHABXMLParserTests.swift | 15 +- openHABTestsSwift/RESTAPITest.swift | 18 +- openHABUITests/OpenHABUITests.swift | 2 - .../ButtonTableRowController.swift | 12 +- .../ComplicationController.swift | 4 - .../ExtensionDelegate.swift | 2 - .../InterfaceController.swift | 20 +- .../NotificationController.swift | 1 - .../PrefsInterfaceController.swift | 12 +- .../URLSessionPinningDelegate.swift | 14 +- openHABWatch Extension/app/AppState.swift | 1 - openHABWatch Extension/domain/Frame.swift | 3 +- openHABWatch Extension/domain/Item.swift | 1 - openHABWatch Extension/domain/Sitemap.swift | 3 +- .../external/AppMessageService.swift | 3 - .../external/OpenHabService.swift | 26 +- .../repository/UserDefaultsRepository.swift | 25 +- 81 files changed, 973 insertions(+), 1204 deletions(-) delete mode 100644 openHAB/OpenHABSDWebImageDownloaderOperation.swift diff --git a/fastlane/SnapshotHelper.swift b/fastlane/SnapshotHelper.swift index aaa2a9a92..b863b6734 100644 --- a/fastlane/SnapshotHelper.swift +++ b/fastlane/SnapshotHelper.swift @@ -52,7 +52,7 @@ enum SnapshotError: Error, CustomDebugStringConvertible { return "Couldn't find Snapshot configuration files - can't detect `Users` dir" case .cannotFindSimulatorHomeDirectory: return "Couldn't find simulator home location. Please, check SIMULATOR_HOST_HOME env variable." - case .cannotAccessSimulatorHomeDirectory(let simulatorHostHome): + case let .cannotAccessSimulatorHomeDirectory(simulatorHostHome): return "Can't prepare environment. Simulator home location is inaccessible. Does \(simulatorHostHome) exist?" case .cannotRunOnPhysicalDevice: return "Can't use Snapshot on a physical device." @@ -70,7 +70,6 @@ open class Snapshot: NSObject { } open class func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) { - Snapshot.app = app Snapshot.waitForAnimations = waitForAnimations @@ -80,7 +79,7 @@ open class Snapshot: NSObject { setLanguage(app) setLocale(app) setLaunchArguments(app) - } catch let error { + } catch { NSLog(error.localizedDescription) } } @@ -117,7 +116,7 @@ open class Snapshot: NSObject { NSLog("Couldn't detect/set locale...") } - if locale.isEmpty && !deviceLanguage.isEmpty { + if locale.isEmpty, !deviceLanguage.isEmpty { locale = Locale(identifier: deviceLanguage).identifier } @@ -160,40 +159,40 @@ open class Snapshot: NSObject { } #if os(OSX) - guard let app = self.app else { - NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") - return - } + guard let app = self.app else { + NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + return + } - app.typeKey(XCUIKeyboardKeySecondaryFn, modifierFlags: []) + app.typeKey(XCUIKeyboardKeySecondaryFn, modifierFlags: []) #else - guard self.app != nil else { - NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") - return - } + guard self.app != nil else { + NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + return + } - let screenshot = XCUIScreen.main.screenshot() - guard var simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"], let screenshotsDir = screenshotsDirectory else { return } + let screenshot = XCUIScreen.main.screenshot() + guard var simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"], let screenshotsDir = screenshotsDirectory else { return } - do { - // The simulator name contains "Clone X of " inside the screenshot file when running parallelized UI Tests on concurrent devices - let regex = try NSRegularExpression(pattern: "Clone [0-9]+ of ") - let range = NSRange(location: 0, length: simulator.count) - simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "") + do { + // The simulator name contains "Clone X of " inside the screenshot file when running parallelized UI Tests on concurrent devices + let regex = try NSRegularExpression(pattern: "Clone [0-9]+ of ") + let range = NSRange(location: 0, length: simulator.count) + simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "") - let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png") - try screenshot.pngRepresentation.write(to: path) - } catch let error { - NSLog("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png") - NSLog(error.localizedDescription) - } + let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png") + try screenshot.pngRepresentation.write(to: path) + } catch { + NSLog("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png") + NSLog(error.localizedDescription) + } #endif } class func waitForLoadingIndicatorToDisappear(within timeout: TimeInterval) { #if os(tvOS) - return + return #endif guard let app = self.app else { @@ -211,27 +210,27 @@ open class Snapshot: NSObject { // on OSX config is stored in /Users//Library // and on iOS/tvOS/WatchOS it's in simulator's home dir #if os(OSX) - guard let user = ProcessInfo().environment["USER"] else { - throw SnapshotError.cannotDetectUser - } + guard let user = ProcessInfo().environment["USER"] else { + throw SnapshotError.cannotDetectUser + } - guard let usersDir = FileManager.default.urls(for: .userDirectory, in: .localDomainMask).first else { - throw SnapshotError.cannotFindHomeDirectory - } + guard let usersDir = FileManager.default.urls(for: .userDirectory, in: .localDomainMask).first else { + throw SnapshotError.cannotFindHomeDirectory + } - homeDir = usersDir.appendingPathComponent(user) + homeDir = usersDir.appendingPathComponent(user) + #else + #if arch(i386) || arch(x86_64) + guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else { + throw SnapshotError.cannotFindSimulatorHomeDirectory + } + guard let homeDirUrl = URL(string: simulatorHostHome) else { + throw SnapshotError.cannotAccessSimulatorHomeDirectory(simulatorHostHome) + } + homeDir = URL(fileURLWithPath: homeDirUrl.path) #else - #if arch(i386) || arch(x86_64) - guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else { - throw SnapshotError.cannotFindSimulatorHomeDirectory - } - guard let homeDirUrl = URL(string: simulatorHostHome) else { - throw SnapshotError.cannotAccessSimulatorHomeDirectory(simulatorHostHome) - } - homeDir = URL(fileURLWithPath: homeDirUrl.path) - #else - throw SnapshotError.cannotRunOnPhysicalDevice - #endif + throw SnapshotError.cannotRunOnPhysicalDevice + #endif #endif return homeDir.appendingPathComponent("Library/Caches/tools.fastlane") } @@ -266,13 +265,13 @@ private extension XCUIElementAttributes { private extension XCUIElementQuery { var networkLoadingIndicators: XCUIElementQuery { - let isNetworkLoadingIndicator = NSPredicate { (evaluatedObject, _) in + let isNetworkLoadingIndicator = NSPredicate { evaluatedObject, _ in guard let element = evaluatedObject as? XCUIElementAttributes else { return false } return element.isNetworkLoadingIndicator } - return self.containing(isNetworkLoadingIndicator) + return containing(isNetworkLoadingIndicator) } var deviceStatusBars: XCUIElementQuery { @@ -282,19 +281,19 @@ private extension XCUIElementQuery { let deviceWidth = app.windows.firstMatch.frame.width - let isStatusBar = NSPredicate { (evaluatedObject, _) in + let isStatusBar = NSPredicate { evaluatedObject, _ in guard let element = evaluatedObject as? XCUIElementAttributes else { return false } return element.isStatusBar(deviceWidth) } - return self.containing(isStatusBar) + return containing(isStatusBar) } } private extension CGFloat { func isBetween(_ numberA: CGFloat, and numberB: CGFloat) -> Bool { - return numberA...numberB ~= self + return numberA ... numberB ~= self } } diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index dd8124c3a..cf0ce21bb 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1122,7 +1122,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + shellScript = "${PODS_ROOT}/SwiftFormat/CommandLineTool/swiftformat ${SRCROOT}\n${PODS_ROOT}/SwiftLint/swiftlint\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/openHAB/AppDelegate.swift b/openHAB/AppDelegate.swift index 0611bafa4..6337aef60 100644 --- a/openHAB/AppDelegate.swift +++ b/openHAB/AppDelegate.swift @@ -22,7 +22,6 @@ var player: AVAudioPlayer? @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - static var appDelegate: AppDelegate! var window: UIWindow? @@ -56,7 +55,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { loadSettingsDefaults() - NetworkConnection.initialize(ignoreSSL: Preferences.ignoreSSL, adapter: OpenHABAccessTokenAdapter() ) + NetworkConnection.initialize(ignoreSSL: Preferences.ignoreSSL, adapter: OpenHABAccessTokenAdapter()) registerForPushNotifications() @@ -103,7 +102,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { guard granted else { return } self.getNotificationSettings() } - } func getNotificationSettings() { @@ -117,7 +115,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - func application(_ application: UIApplication, open url: URL, options: [ UIApplication.OpenURLOptionsKey: Any ]) -> Bool { + func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool { // TODO: Pass this parameters to openHABViewController somehow to open specified sitemap/page and send specified command // Probably need to do this in a way compatible to Android app's URL @@ -135,16 +133,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // This is only informational - on success - DID Register func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { - let deviceTokenString = deviceToken.reduce("") { $0 + String(format: "%02X", $1) } //try "%02.2hhx", os_log("My token is: %{PUBLIC}@", log: .notifications, type: .info, deviceTokenString) - let dataDict = [ - "deviceToken": deviceTokenString, - "deviceId": UIDevice.current.identifierForVendor?.uuidString ?? "" , - "deviceName": UIDevice.current.name - ] + let dataDict = ["deviceToken": deviceTokenString, + "deviceId": UIDevice.current.identifierForVendor?.uuidString ?? "", + "deviceName": UIDevice.current.name] NotificationCenter.default.post(name: NSNotification.Name("apsRegistered"), object: self, userInfo: dataDict) } @@ -154,8 +149,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { - // version without completionHandler is deprecated - // func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) { + // version without completionHandler is deprecated + // func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) { os_log("didReceiveRemoteNotification", log: .notifications, type: .info) if application.applicationState == .active { @@ -174,7 +169,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { player = try AVAudioPlayer(contentsOf: soundPath) player?.numberOfLoops = 0 player?.play() - } catch let error { + } catch { os_log("%{PUBLIC}@", log: .notifications, type: .error, error.localizedDescription) } player = try? AVAudioPlayer(contentsOf: soundPath) @@ -206,7 +201,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } @@ -224,7 +219,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func loadSettingsDefaults() { let prefs = UserDefaults.standard - if prefs.object(forKey: "localUrl") == nil { + if prefs.object(forKey: "localUrl") == nil { prefs.setValue("", forKey: "localUrl") } if prefs.object(forKey: "remoteUrl") == nil { @@ -248,6 +243,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if prefs.object(forKey: "iconType") == nil { prefs.set(false, forKey: "iconType") } - } } diff --git a/openHAB/ClientCertificateManager.swift b/openHAB/ClientCertificateManager.swift index 4b313a71f..6467969fb 100644 --- a/openHAB/ClientCertificateManager.swift +++ b/openHAB/ClientCertificateManager.swift @@ -12,7 +12,7 @@ import Security protocol ClientCertificateManagerDelegate: NSObjectProtocol { // delegate should ask user for a decision on whether to import the client certificate into the keychain func askForClientCertificateImport(_ clientCertificateManager: ClientCertificateManager?) - // delegate should ask user for the export password used to decode the PKCS#12 + // delegate should ask user for the export password used to decode the PKCS#12 func askForCertificatePassword(_ clientCertificateManager: ClientCertificateManager?) // delegate should alert the user that an error occured importing the certificate func alertClientCertificateError(_ clientCertificateManager: ClientCertificateManager?, errMsg: String) @@ -33,11 +33,9 @@ class ClientCertificateManager { } func loadFromKeychain() { - let getIdentityQuery: [String: Any] = [ - kSecClass as String: kSecClassIdentity, - kSecReturnRef as String: true, - kSecMatchLimit as String: kSecMatchLimitAll - ] + let getIdentityQuery: [String: Any] = [kSecClass as String: kSecClassIdentity, + kSecReturnRef as String: true, + kSecMatchLimit as String: kSecMatchLimitAll] var items: CFTypeRef? let status = SecItemCopyMatching(getIdentityQuery as CFDictionary, &items) if status == errSecSuccess { @@ -46,7 +44,7 @@ class ClientCertificateManager { } func getIdentityName(index: Int) -> String { - if index >= 0 && index < clientIdentities.count { + if index >= 0, index < clientIdentities.count { let identity = clientIdentities[index] var cert: SecCertificate? SecIdentityCopyCertificate(identity, &cert) @@ -60,12 +58,10 @@ class ClientCertificateManager { func evaluateTrust(distinguishedNames: [Data]) -> SecIdentity? { // Search the keychain for an identity that matches the DN of the certificate being requested by the server - let getIdentityQuery: [String: Any] = [ - kSecClass as String: kSecClassIdentity, - kSecReturnRef as String: true, - kSecMatchLimit as String: kSecMatchLimitOne, - kSecMatchIssuers as String: distinguishedNames - ] + let getIdentityQuery: [String: Any] = [kSecClass as String: kSecClassIdentity, + kSecReturnRef as String: true, + kSecMatchLimit as String: kSecMatchLimitOne, + kSecMatchIssuers as String: distinguishedNames] var identity: CFTypeRef? let status = SecItemCopyMatching(getIdentityQuery as CFDictionary, &identity) if status == errSecSuccess { @@ -76,15 +72,15 @@ class ClientCertificateManager { func addToKeychain(key: SecKey, cert: SecCertificate) -> OSStatus { // Add the certificate to the keychain - let addCertQuery : [ String: Any ] = [ kSecClass as String: kSecClassCertificate, - kSecValueRef as String: cert ] + let addCertQuery: [String: Any] = [kSecClass as String: kSecClassCertificate, + kSecValueRef as String: cert] var status = SecItemAdd(addCertQuery as NSDictionary, nil) os_log("SecItemAdd(cert) result=%{PUBLIC}d", log: .default, type: .info, status) if status == noErr { - let addKeyQuery : [ String: Any ] = [ kSecClass as String: kSecClassKey, - kSecAttrKeyType as String: kSecAttrKeyTypeRSA, - kSecAttrIsPermanent as String: true, - kSecValueRef as String: key ] + let addKeyQuery: [String: Any] = [kSecClass as String: kSecClassKey, + kSecAttrKeyType as String: kSecAttrKeyTypeRSA, + kSecAttrIsPermanent as String: true, + kSecValueRef as String: key] status = SecItemAdd(addKeyQuery as NSDictionary, nil) os_log("SecItemAdd(key) result=%{PUBLIC}d", log: .default, type: .info, status) if status == noErr { @@ -92,8 +88,8 @@ class ClientCertificateManager { loadFromKeychain() } else { // Private key add failed so clean up the previously added cert - let deleteCertQuery : [ String: Any ] = [ kSecClass as String: kSecClassCertificate, - kSecValueRef as String: cert ] + let deleteCertQuery: [String: Any] = [kSecClass as String: kSecClassCertificate, + kSecValueRef as String: cert] let status = SecItemDelete(deleteCertQuery as NSDictionary) os_log("SecItemDelete(cert) result=%{PUBLIC}d", log: .default, type: .info, status) } @@ -110,13 +106,13 @@ class ClientCertificateManager { var key: SecKey? SecIdentityCopyPrivateKey(identity, &key) - let deleteCertQuery : [ String: Any ] = [ kSecClass as String: kSecClassCertificate, - kSecValueRef as String: cert! ] + let deleteCertQuery: [String: Any] = [kSecClass as String: kSecClassCertificate, + kSecValueRef as String: cert!] var status = SecItemDelete(deleteCertQuery as NSDictionary) os_log("SecItemDelete(cert) result=%{PUBLIC}d", log: .default, type: .info, status) if status == noErr { - let deleteKeyQuery : [ String: Any ] = [ kSecClass as String: kSecClassKey, - kSecValueRef as String: key! ] + let deleteKeyQuery: [String: Any] = [kSecClass as String: kSecClassKey, + kSecValueRef as String: key!] status = SecItemDelete(deleteKeyQuery as NSDictionary) os_log("SecItemDelete(key) result=%{PUBLIC}d", log: .default, type: .info, status) clientIdentities.remove(at: index) @@ -182,7 +178,7 @@ class ClientCertificateManager { private func decodePKCS12() -> OSStatus { // Import PKCS12 client cert var importResult: CFArray? - let status = SecPKCS12Import(importingRawCert! as CFData, [kSecImportExportPassphrase as String: importingPassword ?? "" ] as NSDictionary, &importResult) + let status = SecPKCS12Import(importingRawCert! as CFData, [kSecImportExportPassphrase as String: importingPassword ?? ""] as NSDictionary, &importResult) if status == noErr { // Extract the certifcate and private key let identityDictionaries = importResult as! [[String: Any]] @@ -198,9 +194,9 @@ class ClientCertificateManager { func evaluateTrust(challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) { let dns = challenge.protectionSpace.distinguishedNames if let dns = dns { - let identity = self.evaluateTrust(distinguishedNames: dns) + let identity = evaluateTrust(distinguishedNames: dns) if let identity = identity { - let credential = URLCredential.init(identity: identity, certificates: nil, persistence: URLCredential.Persistence.forSession) + let credential = URLCredential(identity: identity, certificates: nil, persistence: URLCredential.Persistence.forSession) return (.useCredential, credential) } } diff --git a/openHAB/Collection+SafeAccess.swift b/openHAB/Collection+SafeAccess.swift index fefd5738d..358d15456 100644 --- a/openHAB/Collection+SafeAccess.swift +++ b/openHAB/Collection+SafeAccess.swift @@ -10,7 +10,7 @@ import Foundation public extension Collection { // Returns the element at the specified index if it is within bounds, otherwise nil. - subscript (safe index: Index) -> Element? { + subscript(safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } } diff --git a/openHAB/ColorPickerUITableViewCell.swift b/openHAB/ColorPickerUITableViewCell.swift index 30e5a8452..7011063e4 100644 --- a/openHAB/ColorPickerUITableViewCell.swift +++ b/openHAB/ColorPickerUITableViewCell.swift @@ -16,12 +16,11 @@ protocol ColorPickerUITableViewCellDelegate: NSObjectProtocol { } class ColorPickerUITableViewCell: GenericUITableViewCell { - weak var delegate: ColorPickerUITableViewCellDelegate? - @IBOutlet weak var upButton: DynamicButton! - @IBOutlet weak var colorButton: UICircleButton! - @IBOutlet weak var downButton: DynamicButton! + @IBOutlet private var upButton: DynamicButton! + @IBOutlet private var colorButton: UICircleButton! + @IBOutlet private var downButton: DynamicButton! required init?(coder: NSCoder) { os_log("ColorPickerUITableViewCell initWithCoder", log: OSLog.viewCycle, type: .info) @@ -32,7 +31,7 @@ class ColorPickerUITableViewCell: GenericUITableViewCell { separatorInset = .zero } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) selectionStyle = .none @@ -52,7 +51,7 @@ class ColorPickerUITableViewCell: GenericUITableViewCell { upButton?.addTarget(self, action: .upButtonPressed, for: .touchUpInside) downButton?.addTarget(self, action: .downButtonPressed, for: .touchUpInside) downButton?.highlightStokeColor = Colors.hightlightStrokeColor - upButton?.highlightStokeColor = Colors.hightlightStrokeColor + upButton?.highlightStokeColor = Colors.hightlightStrokeColor } @objc @@ -68,7 +67,7 @@ class ColorPickerUITableViewCell: GenericUITableViewCell { } } -fileprivate extension Selector { +private extension Selector { static let upButtonPressed = #selector(ColorPickerUITableViewCell.upButtonPressed) static let downButtonPressed = #selector(ColorPickerUITableViewCell.downButtonPressed) } diff --git a/openHAB/ColorPickerViewController.swift b/openHAB/ColorPickerViewController.swift index 963ea32bd..4a6f2df47 100644 --- a/openHAB/ColorPickerViewController.swift +++ b/openHAB/ColorPickerViewController.swift @@ -55,7 +55,7 @@ class ColorPickerViewController: DefaultColorPickerViewController { os_log("Color changed to HSB(%g, %g, %g).", log: .default, type: .info, hue, saturation, brightness) - self.widget?.sendCommand("\(hue),\(saturation),\(brightness)") + widget?.sendCommand("\(hue),\(saturation),\(brightness)") } } diff --git a/openHAB/ColorUtil.swift b/openHAB/ColorUtil.swift index 15fc1c229..43cea356c 100644 --- a/openHAB/ColorUtil.swift +++ b/openHAB/ColorUtil.swift @@ -9,7 +9,7 @@ import UIKit enum Colors { - static let hightlightStrokeColor: UIColor = .black + static let hightlightStrokeColor: UIColor = .black } func namedColor(toHexString namedColor: String) -> String? { @@ -34,22 +34,20 @@ func namedColor(toHexString namedColor: String) -> String? { } func color(fromHexString hexString: String?) -> UIColor? { - var cString: String = hexString?.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() ?? "x800000" + var cString: String = hexString?.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() ?? "x800000" if !cString.hasPrefix("#"), let namedColor = namedColor(toHexString: cString) { cString = namedColor } if cString.hasPrefix("#") { cString.remove(at: cString.startIndex) } - if (cString.count) != 6 { + if cString.count != 6 { return UIColor.gray } var rgbValue: UInt32 = 0 Scanner(string: cString).scanHexInt32(&rgbValue) - return UIColor( - red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, - green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, - blue: CGFloat(rgbValue & 0x0000FF) / 255.0, - alpha: CGFloat(1.0) - ) + return UIColor(red: CGFloat((rgbValue & 0xff0000) >> 16) / 255.0, + green: CGFloat((rgbValue & 0x00ff00) >> 8) / 255.0, + blue: CGFloat(rgbValue & 0x0000ff) / 255.0, + alpha: CGFloat(1.0)) } diff --git a/openHAB/DrawerUITableViewCell.swift b/openHAB/DrawerUITableViewCell.swift index ef8a68f32..d3c942a14 100644 --- a/openHAB/DrawerUITableViewCell.swift +++ b/openHAB/DrawerUITableViewCell.swift @@ -11,16 +11,15 @@ import os.log import UIKit class DrawerUITableViewCell: UITableViewCell { - - @IBOutlet weak var customTextLabel: UILabel! - @IBOutlet weak var customImageView: UIView! + // swiftlint:disable private_outlet + @IBOutlet private(set) var customTextLabel: UILabel! + @IBOutlet private(set) var customImageView: UIView! required init?(coder: NSCoder) { os_log("DrawerUITableViewCell initWithCoder", log: .viewCycle, type: .info) super.init(coder: coder) separatorInset = .zero - } override func setSelected(_ selected: Bool, animated: Bool) { diff --git a/openHAB/DynamicButtonStyleBell.swift b/openHAB/DynamicButtonStyleBell.swift index 3e8b5717c..cd14b3dd2 100644 --- a/openHAB/DynamicButtonStyleBell.swift +++ b/openHAB/DynamicButtonStyleBell.swift @@ -11,7 +11,6 @@ import UIKit /// Bell symbol style: 🔔 struct DynamicButtonStyleBell: DynamicButtonBuildableStyle { - /// "Bell" style. static var styleName: String { return "Bell" diff --git a/openHAB/DynamicButtonStyleGear.swift b/openHAB/DynamicButtonStyleGear.swift index 35a5a8500..80971fe64 100644 --- a/openHAB/DynamicButtonStyleGear.swift +++ b/openHAB/DynamicButtonStyleGear.swift @@ -15,6 +15,7 @@ struct DynamicButtonStyleGear: DynamicButtonBuildableStyle { static var styleName: String { return "Gear" } + let pathVector: DynamicButtonPathVector init(center: CGPoint, size: CGFloat, offset: CGPoint, lineWidth: CGFloat) { @@ -60,7 +61,7 @@ struct DynamicButtonStyleGear: DynamicButtonBuildableStyle { shape.addLine(to: CGPoint(x: 19.4, y: 13)) shape.close() - shape.apply(CGAffineTransform.init(scaleX: (size - 2 * lineWidth) / 21.6, y: (size - 2 * lineWidth) / 21.6)) + shape.apply(CGAffineTransform(scaleX: (size - 2 * lineWidth) / 21.6, y: (size - 2 * lineWidth) / 21.6)) let radius = size / 4.8 - lineWidth diff --git a/openHAB/Endpoint.swift b/openHAB/Endpoint.swift index 24e6de141..574c30f33 100644 --- a/openHAB/Endpoint.swift +++ b/openHAB/Endpoint.swift @@ -30,70 +30,47 @@ extension Endpoint { } static func watchSitemap(openHABRootUrl: String, sitemapName: String) -> Endpoint { - return Endpoint( - baseURL: openHABRootUrl, - path: "/rest/sitemaps/" + sitemapName, - queryItems: [ - URLQueryItem(name: "jsoncallback", value: "callback") - ] - ) + return Endpoint(baseURL: openHABRootUrl, + path: "/rest/sitemaps/" + sitemapName, + queryItems: [URLQueryItem(name: "jsoncallback", value: "callback")]) } - static func appleRegistration (prefsURL: String, - deviceToken: String, - deviceId: String, - deviceName: String) -> Endpoint { - return Endpoint ( - baseURL: prefsURL, - path: "/addAppleRegistration", - queryItems: [ - URLQueryItem(name: "regId", value: deviceToken), - URLQueryItem(name: "deviceId", value: deviceId), - URLQueryItem(name: "deviceModel", value: deviceName) - ] - ) + static func appleRegistration(prefsURL: String, + deviceToken: String, + deviceId: String, + deviceName: String) -> Endpoint { + return Endpoint(baseURL: prefsURL, + path: "/addAppleRegistration", + queryItems: [URLQueryItem(name: "regId", value: deviceToken), + URLQueryItem(name: "deviceId", value: deviceId), + URLQueryItem(name: "deviceModel", value: deviceName)]) } - static func notification (prefsURL: String) -> Endpoint { - return Endpoint ( - baseURL: prefsURL, - path: "/api/v1/notifications", - queryItems: [ - URLQueryItem(name: "limit", value: "20") - ] - ) + static func notification(prefsURL: String) -> Endpoint { + return Endpoint(baseURL: prefsURL, + path: "/api/v1/notifications", + queryItems: [URLQueryItem(name: "limit", value: "20")]) } - static func tracker (openHABRootUrl: String) -> Endpoint { - return Endpoint ( - baseURL: openHABRootUrl, - path: "/rest/bindings", - queryItems: [] - ) + static func tracker(openHABRootUrl: String) -> Endpoint { + return Endpoint(baseURL: openHABRootUrl, + path: "/rest/bindings", + queryItems: []) } - static func sitemaps (openHABRootUrl: String) -> Endpoint { - return Endpoint ( - baseURL: openHABRootUrl, - path: "/rest/sitemaps", - queryItems: [ - URLQueryItem(name: "limit", value: "20") - ] - ) + static func sitemaps(openHABRootUrl: String) -> Endpoint { + return Endpoint(baseURL: openHABRootUrl, + path: "/rest/sitemaps", + queryItems: [URLQueryItem(name: "limit", value: "20")]) } // swiftlint:disable:next function_parameter_count - static func chart (rootUrl: String, period: String?, type: String?, service: String?, name: String?, legend: Bool?) -> Endpoint { - - let random = Int.random(in: 0..<1000) - var endpoint = Endpoint ( - baseURL: rootUrl, - path: "/chart", - queryItems: [ - URLQueryItem(name: "period", value: period), - URLQueryItem(name: "random", value: String(random)) - ] - ) + static func chart(rootUrl: String, period: String?, type: String?, service: String?, name: String?, legend: Bool?) -> Endpoint { + let random = Int.random(in: 0 ..< 1000) + var endpoint = Endpoint(baseURL: rootUrl, + path: "/chart", + queryItems: [URLQueryItem(name: "period", value: period), + URLQueryItem(name: "random", value: String(random))]) if let type = type, type.isAny(of: "GroupItem", "Group") { endpoint.queryItems.append(URLQueryItem(name: "groups", value: name)) @@ -109,44 +86,33 @@ extension Endpoint { return endpoint } - static func icon (rootUrl: String, version: Int, icon: String?, value: String, iconType: IconType) -> Endpoint { + static func icon(rootUrl: String, version: Int, icon: String?, value: String, iconType: IconType) -> Endpoint { guard let icon = icon, !icon.isEmpty else { return Endpoint(baseURL: "", path: "", queryItems: []) } // determineOH2IconPath if version == 2 { - return Endpoint( - baseURL: rootUrl, - path: "/icon/\(icon)", - queryItems: [ - URLQueryItem(name: "state", value: value ), - URLQueryItem(name: "format", value: (iconType == .png) ? "PNG": "SVG") - ] - ) + return Endpoint(baseURL: rootUrl, + path: "/icon/\(icon)", + queryItems: [URLQueryItem(name: "state", value: value), + URLQueryItem(name: "format", value: (iconType == .png) ? "PNG" : "SVG")]) } else { - return Endpoint( - baseURL: rootUrl, - path: "/images/\(icon).png", - queryItems: [] - ) + return Endpoint(baseURL: rootUrl, + path: "/images/\(icon).png", + queryItems: []) } } - static func iconForDrawer (rootUrl: String, version: Int, icon: String) -> Endpoint { - + static func iconForDrawer(rootUrl: String, version: Int, icon: String) -> Endpoint { if version == 2 { - return Endpoint( - baseURL: rootUrl, - path: "/icon/\(icon).png", - queryItems: [] - ) + return Endpoint(baseURL: rootUrl, + path: "/icon/\(icon).png", + queryItems: []) } else { - return Endpoint( - baseURL: rootUrl, - path: "/images/\(icon).png", - queryItems: [] - ) + return Endpoint(baseURL: rootUrl, + path: "/images/\(icon).png", + queryItems: []) } } } diff --git a/openHAB/FrameUITableViewCell.swift b/openHAB/FrameUITableViewCell.swift index 824c98270..a6628329d 100644 --- a/openHAB/FrameUITableViewCell.swift +++ b/openHAB/FrameUITableViewCell.swift @@ -11,7 +11,6 @@ import UIKit class FrameUITableViewCell: GenericUITableViewCell { - required init?(coder: NSCoder) { super.init(coder: coder) @@ -19,7 +18,7 @@ class FrameUITableViewCell: GenericUITableViewCell { separatorInset = .zero } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) selectionStyle = .none @@ -32,5 +31,4 @@ class FrameUITableViewCell: GenericUITableViewCell { textLabel?.text = widget.label.uppercased() contentView.sizeToFit() } - } diff --git a/openHAB/GenericUITableViewCell.swift b/openHAB/GenericUITableViewCell.swift index 3e4397b8f..322f70f24 100644 --- a/openHAB/GenericUITableViewCell.swift +++ b/openHAB/GenericUITableViewCell.swift @@ -16,7 +16,6 @@ protocol GenericCellCacheProtocol: UITableViewCell { } class GenericUITableViewCell: UITableViewCell { - private var _widget: OpenHABWidget! var widget: OpenHABWidget! { get { @@ -60,16 +59,17 @@ class GenericUITableViewCell: UITableViewCell { } } - @IBOutlet weak var customTextLabel: UILabel! - @IBOutlet weak var customDetailTextLabel: UILabel! - @IBOutlet weak var customDetailTextLabelConstraint: NSLayoutConstraint! + // swiftlint:disable private_outlet + @IBOutlet private(set) var customTextLabel: UILabel! + @IBOutlet private(set) var customDetailTextLabel: UILabel! + @IBOutlet private(set) var customDetailTextLabelConstraint: NSLayoutConstraint! required init?(coder: NSCoder) { super.init(coder: coder) initialize() } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) initialize() } @@ -110,5 +110,4 @@ class GenericUITableViewCell: UITableViewCell { imageView?.kf.cancelDownloadTask() imageView?.image = nil } - } diff --git a/openHAB/MapViewTableViewCell.swift b/openHAB/MapViewTableViewCell.swift index 3e547d982..10ee64249 100644 --- a/openHAB/MapViewTableViewCell.swift +++ b/openHAB/MapViewTableViewCell.swift @@ -14,12 +14,10 @@ class MapViewTableViewCell: GenericUITableViewCell { private var mapView: MKMapView! override var widget: OpenHABWidget! { - get { return super.widget } set(widget) { - let oldLocationCoordinate: CLLocationCoordinate2D? = self.widget?.coordinate let oldLocationTitle = self.widget?.labelText ?? "" let newLocationCoordinate: CLLocationCoordinate2D? = widget?.coordinate @@ -46,10 +44,9 @@ class MapViewTableViewCell: GenericUITableViewCell { mapView.layer.cornerRadius = 4.0 mapView.layer.masksToBounds = true contentView.addSubview(mapView) - } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) mapView = MKMapView(frame: CGRect.zero) diff --git a/openHAB/NSData+HexString.swift b/openHAB/NSData+HexString.swift index 474ce1107..a32c128e2 100644 --- a/openHAB/NSData+HexString.swift +++ b/openHAB/NSData+HexString.swift @@ -24,5 +24,4 @@ extension Data { return String(utf16CodeUnits: hexChars, count: hexChars.count) } - } diff --git a/openHAB/NSObjectExtension.swift b/openHAB/NSObjectExtension.swift index e259c0148..da540fa1b 100644 --- a/openHAB/NSObjectExtension.swift +++ b/openHAB/NSObjectExtension.swift @@ -9,9 +9,7 @@ import Foundation extension NSObject { - func getProperties(from classType: NSObject.Type) -> [String] { - var propertiesCount: CUnsignedInt = 0 let propertiesInAClass = class_copyPropertyList(classType, &propertiesCount) let propertiesArray: [String] @@ -20,7 +18,6 @@ extension NSObject { let property = propertiesInAClass?[i] let strKey = NSString(utf8String: property_getName(property!)) as String? propertiesArray.append(strKey) - } return propertiesArray } diff --git a/openHAB/NetworkConnection.swift b/openHAB/NetworkConnection.swift index 61343b887..c3c851b77 100644 --- a/openHAB/NetworkConnection.swift +++ b/openHAB/NetworkConnection.swift @@ -13,7 +13,7 @@ import os.log // SessionManager --> Session // serverTrustPolicyManager --> serverTrustManager // ServerTrustPolicyManager --> ServerTrustManager -let onReceiveSessionTaskChallenge = { (session: URLSession, task: URLSessionTask, challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) in +let onReceiveSessionTaskChallenge = { (_: URLSession, _: URLSessionTask, challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) in var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling var credential: URLCredential? @@ -30,7 +30,7 @@ let onReceiveSessionTaskChallenge = { (session: URLSession, task: URLSessionTask return (disposition, credential) } -let onReceiveSessionChallenge = { (session: URLSession, challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) in +let onReceiveSessionChallenge = { (_: URLSession, challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) in var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling var credential: URLCredential? @@ -54,7 +54,6 @@ let onReceiveSessionChallenge = { (session: URLSession, challenge: URLAuthentica } class NetworkConnection { - static var shared: NetworkConnection! static var atmosphereTrackingId = "" @@ -66,9 +65,8 @@ class NetworkConnection { init(ignoreSSL: Bool, manager: SessionManager = SessionManager(configuration: URLSessionConfiguration.default, - delegate: SessionDelegate() ), - adapter: RequestAdapter? - ) { + delegate: SessionDelegate()), + adapter: RequestAdapter?) { serverCertificateManager = ServerCertificateManager(ignoreCertificates: ignoreSSL) serverCertificateManager.initializeCertificatesStore() self.manager = manager @@ -86,7 +84,6 @@ class NetworkConnection { deviceToken: String, deviceId: String, deviceName: String, completionHandler: @escaping (DataResponse) -> Void) { - if let url = Endpoint.appleRegistration(prefsURL: prefsURL, deviceToken: deviceToken, deviceId: deviceId, deviceName: deviceName).url { load(from: url, completionHandler: completionHandler) } @@ -94,7 +91,6 @@ class NetworkConnection { static func sitemaps(openHABRootUrl: String, completionHandler: @escaping (DataResponse) -> Void) { - if let url = Endpoint.sitemaps(openHABRootUrl: openHABRootUrl).url { load(from: url, completionHandler: completionHandler) } @@ -109,14 +105,12 @@ class NetworkConnection { static func notification(urlString: String, completionHandler: @escaping (DataResponse) -> Void) { - if let notificationsUrl = Endpoint.notification(prefsURL: urlString).url { load(from: notificationsUrl, completionHandler: completionHandler) } } static func sendCommand(item: OpenHABItem, commandToSend command: String?) -> DataRequest? { - if let commandUrl = URL(string: item.link) { var commandRequest = URLRequest(url: commandUrl) @@ -126,16 +120,16 @@ class NetworkConnection { os_log("Timeout %{PUBLIC}g", log: .default, type: .info, commandRequest.timeoutInterval) let link = item.link - os_log("OpenHABViewController posting %{PUBLIC}@ command to %{PUBLIC}@", log: .default, type: .info, command ?? "", link) + os_log("OpenHABViewController posting %{PUBLIC}@ command to %{PUBLIC}@", log: .default, type: .info, command ?? "", link) os_log("%{PUBLIC}@", log: .default, type: .info, commandRequest.debugDescription) return NetworkConnection.shared.manager.request(commandRequest) - .validate(statusCode: 200..<300) - .responseData { (response) in + .validate(statusCode: 200 ..< 300) + .responseData { response in switch response.result { case .success: os_log("Command sent!", log: .remoteAccess, type: .info) - case .failure(let error): + case let .failure(error): os_log("%{PUBLIC}@ %d", log: .default, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) } } @@ -147,9 +141,8 @@ class NetworkConnection { longPolling: Bool, openHABVersion: Int, completionHandler: @escaping (DataResponse) -> Void) -> DataRequest? { - if pageUrl == "" { - return nil + return nil } os_log("pageUrl = %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, pageUrl) @@ -176,9 +169,8 @@ class NetworkConnection { os_log("OpenHABViewController sending new request", log: .remoteAccess, type: .error) return NetworkConnection.shared.manager.request(pageRequest) - .validate(statusCode: 200..<300) - .responseData (completionHandler: completionHandler) - + .validate(statusCode: 200 ..< 300) + .responseData(completionHandler: completionHandler) } static func load(from url: URL, completionHandler: @escaping (DataResponse) -> Void) { @@ -189,8 +181,8 @@ class NetworkConnection { } os_log("Firing request", log: .viewCycle, type: .debug) let task = NetworkConnection.shared.manager.request(request) - .validate(statusCode: 200..<300) - .responseData (completionHandler: completionHandler) + .validate(statusCode: 200 ..< 300) + .responseData(completionHandler: completionHandler) task.resume() } @@ -200,6 +192,6 @@ class NetworkConnection { } func setRootUrl(_ url: String?) { - self.rootUrl = URL(string: url ?? "") + rootUrl = URL(string: url ?? "") } } diff --git a/openHAB/NewImageTableViewCell.swift b/openHAB/NewImageTableViewCell.swift index 23e0690de..1442b6735 100644 --- a/openHAB/NewImageTableViewCell.swift +++ b/openHAB/NewImageTableViewCell.swift @@ -9,8 +9,7 @@ import UIKit class NewImageTableViewCell: UITableViewCell { - - @IBOutlet weak var customImageView: ScaledHeightImageView! + @IBOutlet private var customImageView: ScaledHeightImageView! override func awakeFromNib() { super.awakeFromNib() // Initialization code diff --git a/openHAB/NewImageUITableViewCell.swift b/openHAB/NewImageUITableViewCell.swift index 6d70a381c..7c4fb4292 100644 --- a/openHAB/NewImageUITableViewCell.swift +++ b/openHAB/NewImageUITableViewCell.swift @@ -17,7 +17,6 @@ enum ImageType { } class NewImageUITableViewCell: GenericUITableViewCell { - var didLoad: (() -> Void)? private var mainImageView: ScaleAspectFitImageView! @@ -55,16 +54,14 @@ class NewImageUITableViewCell: GenericUITableViewCell { contentView.addSubview(mainImageView) - let positionGuide = contentView //contentView.layoutMarginsGuide if more margin would be appreciated + let positionGuide = contentView // contentView.layoutMarginsGuide if more margin would be appreciated mainImageView.translatesAutoresizingMaskIntoConstraints = false // enable autolayout - NSLayoutConstraint.activate([ - mainImageView.leftAnchor.constraint(equalTo: positionGuide.leftAnchor), - mainImageView.rightAnchor.constraint(equalTo: positionGuide.rightAnchor), - mainImageView.topAnchor.constraint(equalTo: positionGuide.topAnchor), - mainImageView.bottomAnchor.constraint(equalTo: positionGuide.bottomAnchor) - ]) + NSLayoutConstraint.activate([mainImageView.leftAnchor.constraint(equalTo: positionGuide.leftAnchor), + mainImageView.rightAnchor.constraint(equalTo: positionGuide.rightAnchor), + mainImageView.topAnchor.constraint(equalTo: positionGuide.topAnchor), + mainImageView.bottomAnchor.constraint(equalTo: positionGuide.bottomAnchor)]) } override func willMove(toSuperview newSuperview: UIView?) { @@ -96,10 +93,10 @@ class NewImageUITableViewCell: GenericUITableViewCell { func loadImage() { switch widgetPayload { - case .embedded(let image): + case let .embedded(image): mainImageView.image = image didLoad?() - case .link(let url): + case let .link(url): guard let url = url else { return } loadRemoteImage(withURL: url) default: @@ -134,8 +131,8 @@ class NewImageUITableViewCell: GenericUITableViewCell { } downloadRequest = NetworkConnection.shared.manager.request(imageRequest) - .validate(statusCode: 200..<300) - .responseData { [weak self] (response) in + .validate(statusCode: 200 ..< 300) + .responseData { [weak self] response in switch response.result { case .success: if let data = response.data { @@ -143,7 +140,7 @@ class NewImageUITableViewCell: GenericUITableViewCell { self?.widget?.image = UIImage(data: data) self?.didLoad?() } - case .failure(let error): + case let .failure(error): os_log("Download failed: %{PUBLIC}@", log: .urlComposition, type: .debug, error.localizedDescription) } } diff --git a/openHAB/NotificationTableViewCell.swift b/openHAB/NotificationTableViewCell.swift index 1fe5f68bc..97dc955b5 100644 --- a/openHAB/NotificationTableViewCell.swift +++ b/openHAB/NotificationTableViewCell.swift @@ -12,9 +12,9 @@ import os.log import UIKit class NotificationTableViewCell: UITableViewCell { - - @IBOutlet weak var customTextLabel: UILabel! - @IBOutlet weak var customDetailTextLabel: UILabel! + // swiftlint:disable private_outlet + @IBOutlet private(set) var customTextLabel: UILabel! + @IBOutlet private(set) var customDetailTextLabel: UILabel! required init?(coder: NSCoder) { os_log("DrawerUITableViewCell initWithCoder", log: .viewCycle, type: .info) diff --git a/openHAB/OpenHABAccessTokenAdapter.swift b/openHAB/OpenHABAccessTokenAdapter.swift index 6364aa4b9..c7440d2ba 100644 --- a/openHAB/OpenHABAccessTokenAdapter.swift +++ b/openHAB/OpenHABAccessTokenAdapter.swift @@ -11,7 +11,6 @@ import Foundation import Kingfisher class OpenHABAccessTokenAdapter: RequestAdapter { - var appData: OpenHABDataObject? { return AppDelegate.appDelegate.appData } @@ -30,7 +29,6 @@ class OpenHABAccessTokenAdapter: RequestAdapter { } extension OpenHABAccessTokenAdapter: ImageDownloadRequestModifier { - func modified(for request: URLRequest) -> URLRequest? { do { return try adapt(request) diff --git a/openHAB/OpenHABClientCertificatesViewController.swift b/openHAB/OpenHABClientCertificatesViewController.swift index 8c58d4976..b5608fb61 100644 --- a/openHAB/OpenHABClientCertificatesViewController.swift +++ b/openHAB/OpenHABClientCertificatesViewController.swift @@ -28,7 +28,7 @@ class OpenHABClientCertificatesViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { super.viewDidAppear(animated) - self.tableView.reloadData() + tableView.reloadData() } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index e7610ebde..79a0bf58e 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -61,7 +61,6 @@ enum DrawerTableType { } class OpenHABDrawerTableViewController: UITableViewController { - static let tableViewCellIdentifier = "DrawerCell" var sitemaps: [OpenHABSitemap] = [] @@ -102,7 +101,7 @@ class OpenHABDrawerTableViewController: UITableViewController { super.viewWillAppear(animated) os_log("OpenHABDrawerTableViewController viewWillAppear", log: .viewCycle, type: .info) - NetworkConnection.sitemaps(openHABRootUrl: openHABRootUrl) { (response) in + NetworkConnection.sitemaps(openHABRootUrl: openHABRootUrl) { response in switch response.result { case .success: UIApplication.shared.isNetworkActivityIndicatorVisible = false @@ -121,7 +120,7 @@ class OpenHABDrawerTableViewController: UITableViewController { self.setStandardDrawerItems() } self.tableView.reloadData() - case .failure(let error): + case let .failure(error): UIApplication.shared.isNetworkActivityIndicatorVisible = false os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) self.drawerItems.removeAll() @@ -157,14 +156,14 @@ class OpenHABDrawerTableViewController: UITableViewController { cell.customImageView.subviews.forEach { $0.removeFromSuperview() } - if indexPath.row < sitemaps.count && !sitemaps.isEmpty { + if indexPath.row < sitemaps.count, !sitemaps.isEmpty { let imageView = UIImageView(frame: cell.customImageView.bounds) cell.customTextLabel?.text = sitemaps[indexPath.row].label if sitemaps[indexPath.row].icon != "" { - if let iconURL = Endpoint.iconForDrawer(rootUrl: openHABRootUrl, version: appData?.openHABVersion ?? 2, icon: sitemaps[indexPath.row].icon ).url { - imageView.kf.setImage (with: iconURL, - placeholder: UIImage(named: "icon-76x76.png")) + if let iconURL = Endpoint.iconForDrawer(rootUrl: openHABRootUrl, version: appData?.openHABVersion ?? 2, icon: sitemaps[indexPath.row].icon).url { + imageView.kf.setImage(with: iconURL, + placeholder: UIImage(named: "icon-76x76.png")) } } else { imageView.image = UIImage(named: "icon-76x76.png") @@ -208,7 +207,7 @@ class OpenHABDrawerTableViewController: UITableViewController { tableView.deselectRow(at: indexPath, animated: false) // First sitemaps - if indexPath.row < sitemaps.count && !sitemaps.isEmpty { + if indexPath.row < sitemaps.count, !sitemaps.isEmpty { let sitemap = sitemaps[indexPath.row] Preferences.defaultSitemap = sitemap.name appData?.rootViewController?.pageUrl = "" @@ -242,7 +241,7 @@ class OpenHABDrawerTableViewController: UITableViewController { private func setStandardDrawerItems() { // check if we are using my.openHAB, add notifications menu item then // Actually this should better test whether the host of the remoteUrl is on openhab.org - if Preferences.remoteUrl.contains("openhab.org") && !Preferences.demomode { + if Preferences.remoteUrl.contains("openhab.org"), !Preferences.demomode { let notificationsItem = OpenHABDrawerItem() notificationsItem.label = "Notifications" notificationsItem.tag = "notifications" diff --git a/openHAB/OpenHABInfoViewController.swift b/openHAB/OpenHABInfoViewController.swift index 011645124..073a81761 100644 --- a/openHAB/OpenHABInfoViewController.swift +++ b/openHAB/OpenHABInfoViewController.swift @@ -11,10 +11,10 @@ import UIKit class OpenHABInfoViewController: UITableViewController { - @IBOutlet var appVersionLabel: UILabel! - @IBOutlet var openHABVersionLabel: UILabel! - @IBOutlet var openHABUUIDLabel: UILabel! - @IBOutlet var openHABSecretLabel: UILabel! + @IBOutlet private var appVersionLabel: UILabel! + @IBOutlet private var openHABVersionLabel: UILabel! + @IBOutlet private var openHABUUIDLabel: UILabel! + @IBOutlet private var openHABSecretLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() diff --git a/openHAB/OpenHABItem.swift b/openHAB/OpenHABItem.swift index a63bb342e..b87c7b0ff 100644 --- a/openHAB/OpenHABItem.swift +++ b/openHAB/OpenHABItem.swift @@ -54,7 +54,6 @@ final class OpenHABItem: NSObject { } func stateAsUIColor() -> UIColor? { - if state == "Uninitialized" { return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) } else { @@ -87,7 +86,6 @@ final class OpenHABItem: NSObject { } extension OpenHABItem { - struct CodingData: Decodable { let type: String let groupType: String? @@ -100,7 +98,7 @@ extension OpenHABItem { extension OpenHABItem.CodingData { var openHABItem: OpenHABItem { - return OpenHABItem(name: self.name, type: self.type, state: self.state, link: self.link, label: self.label, groupType: self.groupType) + return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType) } } @@ -109,7 +107,7 @@ extension CGFloat { let numberFormatter = NumberFormatter() numberFormatter.locale = Locale(identifier: "EN") if let number = numberFormatter.number(from: string) { - self.init(number.floatValue/divisor) + self.init(number.floatValue / divisor) } else { self.init(0) } diff --git a/openHAB/OpenHABLegalViewController.swift b/openHAB/OpenHABLegalViewController.swift index 6f363d1eb..b0a6b0496 100644 --- a/openHAB/OpenHABLegalViewController.swift +++ b/openHAB/OpenHABLegalViewController.swift @@ -11,7 +11,7 @@ import UIKit class OpenHABLegalViewController: UIViewController { - @IBOutlet var legalTextView: UITextView! + @IBOutlet private var legalTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() diff --git a/openHAB/OpenHABNotification.swift b/openHAB/OpenHABNotification.swift index 4e2b129a7..f789adef4 100644 --- a/openHAB/OpenHABNotification.swift +++ b/openHAB/OpenHABNotification.swift @@ -61,7 +61,7 @@ extension OpenHABNotification { // Convenience method to convert a decoded value into a proper OpenHABNotification instance extension OpenHABNotification.CodingData { var openHABNotification: OpenHABNotification { - return OpenHABNotification(message: self.message, created: self.created) + return OpenHABNotification(message: message, created: created) } } diff --git a/openHAB/OpenHABNotificationsViewController.swift b/openHAB/OpenHABNotificationsViewController.swift index a44435e46..7bfc98390 100644 --- a/openHAB/OpenHABNotificationsViewController.swift +++ b/openHAB/OpenHABNotificationsViewController.swift @@ -36,10 +36,10 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat tableView.refreshControl = refreshControl } - self.hamburgerButton = DynamicButton(frame: CGRect(x: 0, y: 0, width: 31, height: 31)) + hamburgerButton = DynamicButton(frame: CGRect(x: 0, y: 0, width: 31, height: 31)) hamburgerButton.setStyle(.hamburger, animated: true) hamburgerButton.addTarget(self, action: #selector(OpenHABViewController.rightDrawerButtonPress(_:)), for: .touchUpInside) - hamburgerButton.strokeColor = self.view.tintColor + hamburgerButton.strokeColor = view.tintColor let hamburgerButtonItem = UIBarButtonItem(customView: hamburgerButton) navigationItem.setRightBarButton(hamburgerButtonItem, animated: true) @@ -53,7 +53,7 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat func loadNotifications() { UIApplication.shared.isNetworkActivityIndicatorVisible = true - NetworkConnection.notification(urlString: Preferences.remoteUrl) { (response) in + NetworkConnection.notification(urlString: Preferences.remoteUrl) { response in switch response.result { case .success: if let data = response.result.value { @@ -72,7 +72,7 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat self.tableView.reloadData() UIApplication.shared.isNetworkActivityIndicatorVisible = false } - case .failure(let error): + case let .failure(error): UIApplication.shared.isNetworkActivityIndicatorVisible = false os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) self.refreshControl?.endRefreshing() @@ -114,8 +114,8 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat icon: notification.icon, value: "", iconType: .png).url { - cell?.imageView?.kf.setImage (with: iconUrl, - placeholder: UIImage(named: "icon-76x76.png")) + cell?.imageView?.kf.setImage(with: iconUrl, + placeholder: UIImage(named: "icon-76x76.png")) } if cell?.responds(to: #selector(setter: NotificationTableViewCell.preservesSuperviewLayoutMargins)) ?? false { @@ -141,7 +141,6 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat } extension UIBarButtonItem { - static func menuButton(_ target: Any?, action: Selector, imageName: String) -> UIBarButtonItem { let button = UIButton(type: .system) button.setImage(UIImage(named: imageName), for: .normal) diff --git a/openHAB/OpenHABNotificationsViewControllerTableViewController.swift b/openHAB/OpenHABNotificationsViewControllerTableViewController.swift index 58aca59b2..67ee1fe0d 100644 --- a/openHAB/OpenHABNotificationsViewControllerTableViewController.swift +++ b/openHAB/OpenHABNotificationsViewControllerTableViewController.swift @@ -12,7 +12,6 @@ import SDWebImage import UIKit class OpenHABNotificationsViewController: UITableViewController { - static let tableViewCellIdentifier = "NotificationCell" var notifications: NSMutableArray = [] @@ -36,7 +35,6 @@ class OpenHABNotificationsViewController: UITableViewController { } let rightDrawerButton = MMDrawerBarButtonItem(target: self, action: #selector(OpenHABNotificationsViewController.rightDrawerButtonPress(_:))) navigationItem.setRightBarButton(rightDrawerButton, animated: true) - } override func viewWillAppear(_ animated: Bool) { @@ -62,7 +60,7 @@ class OpenHABNotificationsViewController: UITableViewController { operation = OpenHABHTTPRequestOperation(request: notificationsRequest as URLRequest) } operation?.responseSerializer = AFJSONResponseSerializer() - operation?.setCompletionBlockWithSuccess({ operation, responseObject in + operation?.setCompletionBlockWithSuccess({ _, responseObject in let response = responseObject as? Data self.notifications = [] print("Notifications response") @@ -166,5 +164,4 @@ class OpenHABNotificationsViewController: UITableViewController { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } - } diff --git a/openHAB/OpenHABSDWebImageDownloaderOperation.swift b/openHAB/OpenHABSDWebImageDownloaderOperation.swift deleted file mode 100644 index 630778561..000000000 --- a/openHAB/OpenHABSDWebImageDownloaderOperation.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// OpenHABSDWebImageDownloaderOperation.swift -// openHAB -// -// Created by David O'Neill on 06/03/19. -// Copyright (c) 2019 David O'Neill. All rights reserved. -// - -import SDWebImage - -class OpenHABSDWebImageDownloaderOperation: SDWebImageDownloaderOperation { - override func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { -<<<<<<< HEAD - if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { - let dns = challenge.protectionSpace.distinguishedNames - if dns != nil { - let identity = NetworkConnection.clientCertificateManager.evaluateTrust(distinguishedNames: dns!) - if identity != nil { - let credential = URLCredential.init(identity: identity!, certificates: nil, persistence: URLCredential.Persistence.forSession) - let disposition = URLSession.AuthChallengeDisposition.useCredential - completionHandler(disposition, credential) - return - } - } - let disposition = URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge - completionHandler(disposition, nil) - return - } - - // Not a client certificate request to run the default handler - super.urlSession(session, task: task, didReceive: challenge, completionHandler: completionHandler) -======= - let policy = AFRememberingSecurityPolicy() - let result = policy.handleAuthenticationChallenge(challenge: challenge) - switch result.0 { - case .useCredential: - completionHandler(result.0, result.1) - default: - // Not a client certificate request to run the default handler - super.urlSession(session, task: task, didReceive: challenge, completionHandler: completionHandler) - } ->>>>>>> master - } -} diff --git a/openHAB/OpenHABSelectionTableViewController.swift b/openHAB/OpenHABSelectionTableViewController.swift index 5c6e1c199..736e6e6d6 100644 --- a/openHAB/OpenHABSelectionTableViewController.swift +++ b/openHAB/OpenHABSelectionTableViewController.swift @@ -34,7 +34,7 @@ class OpenHABSelectionTableViewController: UITableViewController { // self.navigationItem.rightBarButtonItem = self.editButtonItem; } -// MARK: - Table view data source + // MARK: - Table view data source override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return mappings.count diff --git a/openHAB/OpenHABSettingsViewController.swift b/openHAB/OpenHABSettingsViewController.swift index 9c96ba334..14112c5a9 100644 --- a/openHAB/OpenHABSettingsViewController.swift +++ b/openHAB/OpenHABSettingsViewController.swift @@ -25,15 +25,15 @@ class OpenHABSettingsViewController: UITableViewController, UITextFieldDelegate return AppDelegate.appDelegate.appData } - @IBOutlet var settingsTableView: UITableView! - @IBOutlet weak var demomodeSwitch: UISwitch! - @IBOutlet weak var passwordTextField: UITextField! - @IBOutlet weak var usernameTextField: UITextField! - @IBOutlet weak var remoteUrlTextField: UITextField! - @IBOutlet weak var localUrlTextField: UITextField! - @IBOutlet weak var idleOffSwitch: UISwitch! - @IBOutlet weak var ignoreSSLSwitch: UISwitch! - @IBOutlet weak var iconSegmentedControl: UISegmentedControl! + @IBOutlet private var settingsTableView: UITableView! + @IBOutlet private var demomodeSwitch: UISwitch! + @IBOutlet private var passwordTextField: UITextField! + @IBOutlet private var usernameTextField: UITextField! + @IBOutlet private var remoteUrlTextField: UITextField! + @IBOutlet private var localUrlTextField: UITextField! + @IBOutlet private var idleOffSwitch: UISwitch! + @IBOutlet private var ignoreSSLSwitch: UISwitch! + @IBOutlet private var iconSegmentedControl: UISegmentedControl! required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) @@ -117,7 +117,7 @@ class OpenHABSettingsViewController: UITableViewController, UITextFieldDelegate override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { settingsTableView.deselectRow(at: indexPath, animated: true) os_log("Row selected %d %d", log: .notifications, type: .info, indexPath.section, indexPath.row) - if indexPath.section == 1 && indexPath.row == 2 { + if indexPath.section == 1, indexPath.row == 2 { os_log("Clearing image cache", log: .viewCycle, type: .info) } } @@ -199,13 +199,11 @@ class OpenHABSettingsViewController: UITableViewController, UITextFieldDelegate } func sendSettingsToWatch() { - WatchService.singleton.sendToWatch( - Preferences.localUrl, - remoteUrl: Preferences.remoteUrl, - username: Preferences.username, - password: Preferences.password, - sitemapName: "watch", - ignoreSSL: Preferences.ignoreSSL) + WatchService.singleton.sendToWatch(Preferences.localUrl, + remoteUrl: Preferences.remoteUrl, + username: Preferences.username, + password: Preferences.password, + sitemapName: "watch", + ignoreSSL: Preferences.ignoreSSL) } - } diff --git a/openHAB/OpenHABSitemap.swift b/openHAB/OpenHABSitemap.swift index 86c772edc..5566a59d6 100644 --- a/openHAB/OpenHABSitemap.swift +++ b/openHAB/OpenHABSitemap.swift @@ -71,7 +71,6 @@ final class OpenHABSitemap: NSObject { } extension OpenHABSitemap { - struct CodingData: Decodable { let name: String let label: String @@ -125,13 +124,11 @@ extension OpenHABSitemap { extension OpenHABSitemap.CodingData { var openHABSitemap: OpenHABSitemap { - return OpenHABSitemap( - name: self.name, - icon: self.icon ?? "", - label: self.label, - link: self.link, - leaf: self.page.leaf, - homepageLink: self.page.link - ) + return OpenHABSitemap(name: name, + icon: icon ?? "", + label: label, + link: link, + leaf: page.leaf, + homepageLink: page.link) } } diff --git a/openHAB/OpenHABSitemapPage.swift b/openHAB/OpenHABSitemapPage.swift index eb55745e8..7607f91e3 100644 --- a/openHAB/OpenHABSitemapPage.swift +++ b/openHAB/OpenHABSitemapPage.swift @@ -31,7 +31,7 @@ class OpenHABSitemapPage: NSObject { tempWidgets.flatten(widgets) self.widgets = tempWidgets self.widgets.forEach { - $0.sendCommand = { [weak self] (item, command) in + $0.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } } @@ -53,7 +53,7 @@ class OpenHABSitemapPage: NSObject { tempWidgets.flatten(widgets) widgets = tempWidgets widgets.forEach { - $0.sendCommand = { [weak self] (item, command) in + $0.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } } @@ -65,12 +65,11 @@ class OpenHABSitemapPage: NSObject { self.title = title self.link = link self.leaf = leaf - self.widgets = expandedWidgets - self.widgets.forEach { - $0.sendCommand = { [weak self] (item, command) in + widgets = expandedWidgets + widgets.forEach { + $0.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } - } } @@ -83,18 +82,17 @@ class OpenHABSitemapPage: NSObject { } extension OpenHABSitemapPage { - func filter (_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> OpenHABSitemapPage { - let filteredOpenHABSitemapPage = OpenHABSitemapPage(pageId: self.pageId, - title: self.title, - link: self.link, - leaf: self.leaf, - expandedWidgets: try self.widgets.filter(isIncluded)) + func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> OpenHABSitemapPage { + let filteredOpenHABSitemapPage = OpenHABSitemapPage(pageId: pageId, + title: title, + link: link, + leaf: leaf, + expandedWidgets: try widgets.filter(isIncluded)) return filteredOpenHABSitemapPage } } extension OpenHABSitemapPage { - struct CodingData: Decodable { let pageId: String? let title: String? @@ -114,7 +112,7 @@ extension OpenHABSitemapPage { extension OpenHABSitemapPage.CodingData { var openHABSitemapPage: OpenHABSitemapPage { - let mappedWidgets = self.widgets?.map { $0.openHABWidget } ?? [] - return OpenHABSitemapPage(pageId: self.pageId ?? "", title: self.title ?? "", link: self.link ?? "", leaf: self.leaf ?? false, widgets: mappedWidgets) + let mappedWidgets = widgets?.map { $0.openHABWidget } ?? [] + return OpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) } } diff --git a/openHAB/OpenHABTracker.swift b/openHAB/OpenHABTracker.swift index 033b39c4a..13dd5aee1 100644 --- a/openHAB/OpenHABTracker.swift +++ b/openHAB/OpenHABTracker.swift @@ -66,7 +66,7 @@ class OpenHABTracker: NSObject { } else { let request = URLRequest(url: URL(string: openHABLocalUrl)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 2.0) NetworkConnection.shared.manager.request(request) - .validate(statusCode: 200..<300) + .validate(statusCode: 200 ..< 300) .responseData { response in switch response.result { case .success: @@ -133,14 +133,13 @@ class OpenHABTracker: NSObject { if let changedReach = notification?.object as? Reachability { let nStatus = changedReach.connection if nStatus != oldReachabilityStatus { - if let oldReachabilityStatus = oldReachabilityStatus { //}, let nStatus = nStatus { + if let oldReachabilityStatus = oldReachabilityStatus { // }, let nStatus = nStatus { os_log("Network status changed from %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, string(from: oldReachabilityStatus) ?? "", string(from: nStatus) ?? "") - } oldReachabilityStatus = nStatus if let delegate = delegate as? OpenHABTrackerExtendedDelegate { // if let nStatus = nStatus { - delegate.openHABTrackingNetworkChange(nStatus) + delegate.openHABTrackingNetworkChange(nStatus) // } } } @@ -171,7 +170,7 @@ class OpenHABTracker: NSObject { func isNetworkConnected2() -> Bool { let networkReach = Reachability() - return (networkReach?.connection == .wifi || networkReach?.connection == .cellular ) ? true : false + return (networkReach?.connection == .wifi || networkReach?.connection == .cellular) ? true : false } func isNetworkWiFi() -> Bool { @@ -196,14 +195,11 @@ class OpenHABTracker: NSObject { case .cellular: return "WWAN" } } - } extension OpenHABTracker: NetServiceDelegate, NetServiceBrowserDelegate { - // NSNetService delegate methods for publication func netServiceDidResolveAddress(_ resolvedNetService: NetService) { - func getStringIp(fromAddressData dataIn: Data?) -> String? { var ipString: String? let data = dataIn! as NSData @@ -235,7 +231,7 @@ extension OpenHABTracker: NetServiceDelegate, NetServiceBrowserDelegate { extension NSData { func castToCPointer() -> T { let mem = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) - self.getBytes(mem, length: MemoryLayout.size) + getBytes(mem, length: MemoryLayout.size) return mem.move() } } diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 8ee074434..cc54b0357 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -36,7 +36,6 @@ protocol ModalHandler: AnyObject { } struct SVGProcessor: ImageProcessor { - // `identifier` should be the same for processors with the same properties/functionality // It will be used when storing and retrieving the image to/from cache. let identifier = "org.openhab.svgprocessor" @@ -44,10 +43,10 @@ struct SVGProcessor: ImageProcessor { // Convert input data/image to target image and return it. func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> Image? { switch item { - case .image(let image): + case let .image(image): print("already an image") return image - case .data(let data): + case let .data(data): if let image = SVGKImage(data: data) { return image.uiImage } else { @@ -61,7 +60,6 @@ private let openHABViewControllerMapViewCellReuseIdentifier = "OpenHABViewContro private let openHABViewControllerImageViewCellReuseIdentifier = "OpenHABViewControllerImageViewCellReuseIdentifier" class OpenHABViewController: UIViewController { - var tracker: OpenHABTracker? var hamburgerButton: DynamicButton! private var selectedWidgetRow: Int = 0 @@ -94,6 +92,7 @@ class OpenHABViewController: UIViewController { return currentPage } } + // App wide data access // https://stackoverflow.com/questions/45832155/how-do-i-refactor-my-code-to-call-appdelegate-on-the-main-thread var appData: OpenHABDataObject? { @@ -111,7 +110,7 @@ class OpenHABViewController: UIViewController { return search.isActive && !searchBarIsEmpty } - @IBOutlet var widgetTableView: UITableView! + @IBOutlet private var widgetTableView: UITableView! // Here goes everything about view loading, appearing, disappearing, entering background and becoming active override func viewDidLoad() { @@ -124,8 +123,8 @@ class OpenHABViewController: UIViewController { NotificationCenter.default.addObserver(self, selector: #selector(OpenHABViewController.didEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(OpenHABViewController.didBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) - self.registerTableViewCells() - self.configureTableView() + registerTableViewCells() + configureTableView() refreshControl = UIRefreshControl() @@ -134,18 +133,18 @@ class OpenHABViewController: UIViewController { widgetTableView.refreshControl = refreshControl } - self.hamburgerButton = DynamicButton(frame: CGRect(x: 0, y: 0, width: 31, height: 31)) + hamburgerButton = DynamicButton(frame: CGRect(x: 0, y: 0, width: 31, height: 31)) hamburgerButton.setStyle(.hamburger, animated: true) hamburgerButton.addTarget(self, action: #selector(OpenHABViewController.rightDrawerButtonPress(_:)), for: .touchUpInside) - hamburgerButton.strokeColor = self.view.tintColor + hamburgerButton.strokeColor = view.tintColor let hamburgerButtomItem = UIBarButtonItem(customView: hamburgerButton) navigationItem.setRightBarButton(hamburgerButtomItem, animated: true) - self.navigationController?.navigationBar.prefersLargeTitles = true + navigationController?.navigationBar.prefersLargeTitles = true search.searchResultsUpdater = self - self.navigationItem.searchController = search + navigationItem.searchController = search search.obscuresBackgroundDuringPresentation = false search.searchBar.placeholder = "Search openHAB items" @@ -200,7 +199,6 @@ class OpenHABViewController: UIViewController { } } ImageDownloader.default.authenticationChallengeResponder = self - } override func viewWillDisappear(_ animated: Bool) { @@ -223,7 +221,6 @@ class OpenHABViewController: UIViewController { && $0.secondAttribute == .notAnAttribute && $0.constant > 0 }) { - UIView.performWithoutAnimation { searchBarHeightConstraint.constant = 0 searchBarSuperview.superview?.layoutIfNeeded() @@ -249,7 +246,7 @@ class OpenHABViewController: UIViewController { if idleOff { UIApplication.shared.isIdleTimerDisabled = true } - if isViewLoaded && view.window != nil && pageUrl != "" { + if isViewLoaded, view.window != nil, pageUrl != "" { if !pageNetworkStatusChanged() { os_log("OpenHABViewController isViewLoaded, restarting network activity", log: .viewCycle, type: .info) loadPage(false) @@ -267,8 +264,8 @@ class OpenHABViewController: UIViewController { // Enable gestures. The left and/or right menus must be set up above for these to work. // Note that these continue to work on the Navigation Controller independent of the View Controller it displays! - SideMenuManager.default.addPanGestureToPresent(toView: self.navigationController!.navigationBar) - SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.navigationController!.view) + SideMenuManager.default.addPanGestureToPresent(toView: navigationController!.navigationBar) + SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: navigationController!.view) let presentationStyle: SideMenuPresentationStyle = .menuSlideIn presentationStyle.presentingEndAlpha = 0 @@ -318,14 +315,14 @@ class OpenHABViewController: UIViewController { func doRegisterAps() { let prefsURL = Preferences.remoteUrl if prefsURL.contains("openhab.org") { - if deviceId != "" && deviceToken != "" && deviceName != "" { + if deviceId != "", deviceToken != "", deviceName != "" { os_log("Registering notifications with %{PUBLIC}@", log: .notifications, type: .info, prefsURL) - NetworkConnection.register(prefsURL: prefsURL, deviceToken: deviceToken, deviceId: deviceId, deviceName: deviceName) { (response) in - switch response.result { - case .success: - os_log("my.openHAB registration sent", log: .notifications, type: .info) - case .failure(let error): - os_log("my.openHAB registration failed %{PUBLIC}@ %d", log: .notifications, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + NetworkConnection.register(prefsURL: prefsURL, deviceToken: deviceToken, deviceId: deviceId, deviceName: deviceName) { response in + switch response.result { + case .success: + os_log("my.openHAB registration sent", log: .notifications, type: .info) + case let .failure(error): + os_log("my.openHAB registration failed %{PUBLIC}@ %d", log: .notifications, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) } } } @@ -393,8 +390,7 @@ class OpenHABViewController: UIViewController { currentPageOperation = NetworkConnection.page(pageUrl: pageUrl, longPolling: longPolling, - openHABVersion: appData?.openHABVersion ?? 2 - ) { [weak self] (response) in + openHABVersion: appData?.openHABVersion ?? 2) { [weak self] response in guard let self = self else { return } switch response.result { @@ -429,7 +425,7 @@ class OpenHABViewController: UIViewController { openHABSitemapPage = try { let sitemapPageCodingData = try data.decoded() as OpenHABSitemapPage.CodingData return sitemapPageCodingData.openHABSitemapPage - }() + }() } catch { os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } @@ -440,7 +436,7 @@ class OpenHABViewController: UIViewController { self.filterContentForSearchText(self.search.searchBar.text) } - self.currentPage?.sendCommand = { [weak self] (item, command) in + self.currentPage?.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } self.widgetTableView.reloadData() @@ -448,12 +444,12 @@ class OpenHABViewController: UIViewController { self.refreshControl?.endRefreshing() self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] self.loadPage(true) - case .failure(let error): + case let .failure(error): UIApplication.shared.isNetworkActivityIndicatorVisible = false os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) NetworkConnection.atmosphereTrackingId = "" - if (error as NSError?)?.code == -1001 && longPolling { + if (error as NSError?)?.code == -1001, longPolling { os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) self.loadPage(false) } else if (error as NSError?)?.code == -999 { @@ -503,7 +499,7 @@ class OpenHABViewController: UIViewController { // Select sitemap func selectSitemap() { - NetworkConnection.sitemaps(openHABRootUrl: openHABRootUrl) { (response) in + NetworkConnection.sitemaps(openHABRootUrl: openHABRootUrl) { response in switch response.result { case .success: UIApplication.shared.isNetworkActivityIndicatorVisible = false @@ -542,7 +538,7 @@ class OpenHABViewController: UIViewController { } self.widgetTableView.reloadData() UIApplication.shared.isNetworkActivityIndicatorVisible = false - case .failure(let error): + case let .failure(error): os_log("%{PUBLIC}@ %d", log: .default, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) DispatchQueue.main.async { UIApplication.shared.isNetworkActivityIndicatorVisible = false @@ -636,7 +632,7 @@ class OpenHABViewController: UIViewController { filteredPage = currentPage?.filter { $0.label.lowercased().contains(searchText.lowercased()) && $0.type != "Frame" } - filteredPage?.sendCommand = { [weak self] (item, command) in + filteredPage?.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) } widgetTableView.reloadData() @@ -654,14 +650,13 @@ class OpenHABViewController: UIViewController { } func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool) { - self.hamburgerButton.setStyle(.hamburger, animated: animated) + hamburgerButton.setStyle(.hamburger, animated: animated) } - } // MARK: - OpenHABTrackerDelegate -extension OpenHABViewController: OpenHABTrackerDelegate { +extension OpenHABViewController: OpenHABTrackerDelegate { func openHABTracked(_ openHABUrl: URL?) { os_log("OpenHABViewController openHAB URL = %{PUBLIC}@", log: .remoteAccess, type: .error, "\(openHABUrl!)") @@ -672,7 +667,7 @@ extension OpenHABViewController: OpenHABTrackerDelegate { appData?.openHABRootUrl = openHABRootUrl NetworkConnection.shared.setRootUrl(openHABRootUrl) - NetworkConnection.tracker(openHABRootUrl: openHABRootUrl) { (response) in + NetworkConnection.tracker(openHABRootUrl: openHABRootUrl) { response in switch response.result { case .success: os_log("This is an openHAB 2.X", log: .remoteAccess, type: .info) @@ -681,7 +676,7 @@ extension OpenHABViewController: OpenHABTrackerDelegate { UIApplication.shared.isNetworkActivityIndicatorVisible = false } self.selectSitemap() - case .failure(let error): + case let .failure(error): os_log("This is an openHAB 1.X", log: .remoteAccess, type: .info) self.appData?.openHABVersion = 1 @@ -731,6 +726,7 @@ extension OpenHABViewController: OpenHABTrackerDelegate { } // MARK: - OpenHABSelectionTableViewControllerDelegate + extension OpenHABViewController: OpenHABSelectionTableViewControllerDelegate { // send command on selected selection widget mapping func didSelectWidgetMapping(_ selectedMappingIndex: Int) { @@ -741,15 +737,15 @@ extension OpenHABViewController: OpenHABSelectionTableViewControllerDelegate { } // MARK: - UISearchResultsUpdating -extension OpenHABViewController: UISearchResultsUpdating { +extension OpenHABViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { filterContentForSearchText(searchController.searchBar.text) } - } // MARK: - ColorPickerUITableViewCellDelegate + extension OpenHABViewController: ColorPickerUITableViewCellDelegate { func didPressColorButton(_ cell: ColorPickerUITableViewCell?) { let colorPickerViewController = storyboard?.instantiateViewController(withIdentifier: "ColorPickerViewController") as? ColorPickerViewController @@ -765,13 +761,14 @@ extension OpenHABViewController: ColorPickerUITableViewCellDelegate { } // MARK: - ServerCertificateManagerDelegate + extension OpenHABViewController: ServerCertificateManagerDelegate { // delegate should ask user for a decision on what to do with invalid certificate func evaluateServerTrust(_ policy: ServerCertificateManager?, summary certificateSummary: String?, forDomain domain: String?) { DispatchQueue.main.async { let alertView = UIAlertController(title: "SSL Certificate Warning", message: "SSL Certificate presented by \(certificateSummary ?? "") for \(domain ?? "") is invalid. Do you want to proceed?", preferredStyle: .alert) alertView.addAction(UIAlertAction(title: "Abort", style: .default) { _ in policy?.evaluateResult = .deny }) - alertView.addAction(UIAlertAction(title: "Once", style: .default) { _ in policy?.evaluateResult = .permitOnce }) + alertView.addAction(UIAlertAction(title: "Once", style: .default) { _ in policy?.evaluateResult = .permitOnce }) alertView.addAction(UIAlertAction(title: "Always", style: .default) { _ in policy?.evaluateResult = .permitAlways }) self.present(alertView, animated: true) {} } @@ -781,8 +778,8 @@ extension OpenHABViewController: ServerCertificateManagerDelegate { func evaluateCertificateMismatch(_ policy: ServerCertificateManager?, summary certificateSummary: String?, forDomain domain: String?) { DispatchQueue.main.async { let alertView = UIAlertController(title: "SSL Certificate Warning", message: "SSL Certificate presented by \(certificateSummary ?? "") for \(domain ?? "") doesn't match the record. Do you want to proceed?", preferredStyle: .alert) - alertView.addAction(UIAlertAction(title: "Abort", style: .default) { _ in policy?.evaluateResult = .deny }) - alertView.addAction(UIAlertAction(title: "Once", style: .default) { _ in policy?.evaluateResult = .permitOnce }) + alertView.addAction(UIAlertAction(title: "Abort", style: .default) { _ in policy?.evaluateResult = .deny }) + alertView.addAction(UIAlertAction(title: "Once", style: .default) { _ in policy?.evaluateResult = .permitOnce }) alertView.addAction(UIAlertAction(title: "Always", style: .default) { _ in policy?.evaluateResult = .permitAlways }) self.present(alertView, animated: true) {} } @@ -790,8 +787,8 @@ extension OpenHABViewController: ServerCertificateManagerDelegate { } // MARK: - ClientCertificateManagerDelegate -extension OpenHABViewController: ClientCertificateManagerDelegate { +extension OpenHABViewController: ClientCertificateManagerDelegate { // delegate should ask user for a decision on whether to import the client certificate into the keychain func askForClientCertificateImport(_ clientCertificateManager: ClientCertificateManager?) { DispatchQueue.main.async { @@ -820,7 +817,7 @@ extension OpenHABViewController: ClientCertificateManagerDelegate { let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (_: UIAlertAction) in clientCertificateManager!.clientCertificateRejected() } - alertController.addTextField { (textField) in + alertController.addTextField { textField in textField.placeholder = "Password" textField.isSecureTextEntry = true } @@ -842,6 +839,7 @@ extension OpenHABViewController: ClientCertificateManagerDelegate { } // MARK: - ModalHandler + extension OpenHABViewController: ModalHandler { func modalDismissed(to: TargetController) { switch to { @@ -866,14 +864,15 @@ extension OpenHABViewController: ModalHandler { } // MARK: - UISideMenuNavigationControllerDelegate + extension OpenHABViewController: SideMenuNavigationControllerDelegate { func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) { - self.hamburgerButton.setStyle(.arrowRight, animated: animated) + hamburgerButton.setStyle(.arrowRight, animated: animated) guard let drawer = menu.viewControllers.first as? OpenHABDrawerTableViewController, - (drawer.delegate == nil || drawer.openHABRootUrl.isEmpty) - else { - return + drawer.delegate == nil || drawer.openHABRootUrl.isEmpty + else { + return } drawer.openHABRootUrl = openHABRootUrl drawer.delegate = self @@ -882,8 +881,8 @@ extension OpenHABViewController: SideMenuNavigationControllerDelegate { } // MARK: - UITableViewDelegate, UITableViewDataSource -extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { +extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if currentPage != nil { if isFiltering { @@ -965,31 +964,30 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { } // No icon is needed for image, video, frame and web widgets - if (widget?.icon != nil) && !( (cell is NewImageUITableViewCell) || (cell is VideoUITableViewCell) || (cell is FrameUITableViewCell) || (cell is WebUITableViewCell) ) { - + if widget?.icon != nil, !((cell is NewImageUITableViewCell) || (cell is VideoUITableViewCell) || (cell is FrameUITableViewCell) || (cell is WebUITableViewCell)) { if let urlc = Endpoint.icon(rootUrl: openHABRootUrl, - version: appData?.openHABVersion ?? 2, - icon: widget?.icon, - value: widget?.item?.state ?? "", - iconType: iconType).url { + version: appData?.openHABVersion ?? 2, + icon: widget?.icon, + value: widget?.item?.state ?? "", + iconType: iconType).url { var imageRequest = URLRequest(url: urlc) imageRequest.timeoutInterval = 10.0 let reportOnResults: ((Swift.Result) -> Void)? = { result in switch result { - case .success(let value): + case let .success(value): os_log("Task done for: %{PUBLIC}@", log: .viewCycle, type: .info, value.source.url?.absoluteString ?? "") - case .failure (let error): + case let .failure(error): os_log("Job failed: %{PUBLIC}@", log: .viewCycle, type: .info, error.localizedDescription) } } - switch self.iconType { - case .png : - cell.imageView?.kf.setImage (with: urlc, - placeholder: UIImage(named: "blankicon.png"), - completionHandler: reportOnResults) + switch iconType { + case .png: + cell.imageView?.kf.setImage(with: urlc, + placeholder: UIImage(named: "blankicon.png"), + completionHandler: reportOnResults) case .svg: cell.imageView?.kf.setImage(with: urlc, placeholder: UIImage(named: "blankicon.png"), @@ -1006,7 +1004,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { cell.backgroundColor = UIColor.systemBackground } else { cell.backgroundColor = UIColor.white - } + } } if let cell = cell as? GenericUITableViewCell { @@ -1016,7 +1014,6 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { // Check if this is not the last row in the widgets list if indexPath.row < (relevantPage?.widgets.count ?? 1) - 1 { - let nextWidget: OpenHABWidget? = relevantPage?.widgets[indexPath.row + 1] if let type = nextWidget?.type, type.isAny(of: "Frame", "Image", "Video", "Webview", "Chart") { cell.separatorInset = UIEdgeInsets.zero @@ -1078,25 +1075,20 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { } extension OpenHABViewController: AuthenticationChallengeResponsable { - // sessionDelegate.onReceiveSessionTaskChallenge - func downloader( - _ downloader: ImageDownloader, - task: URLSessionTask, - didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - + func downloader(_ downloader: ImageDownloader, + task: URLSessionTask, + didReceive challenge: URLAuthenticationChallenge, + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let (disposition, credential) = onReceiveSessionTaskChallenge(URLSession(), task, challenge) - completionHandler (disposition, credential) + completionHandler(disposition, credential) } // sessionDelegate.onReceiveSessionChallenge - func downloader( - _ downloader: ImageDownloader, - didReceive challenge: URLAuthenticationChallenge, - completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - + func downloader(_ downloader: ImageDownloader, + didReceive challenge: URLAuthenticationChallenge, + completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let (disposition, credential) = onReceiveSessionChallenge(URLSession(), challenge) - completionHandler (disposition, credential) + completionHandler(disposition, credential) } } diff --git a/openHAB/OpenHABWidget.swift b/openHAB/OpenHABWidget.swift index 536655690..ba9839de6 100644 --- a/openHAB/OpenHABWidget.swift +++ b/openHAB/OpenHABWidget.swift @@ -50,13 +50,11 @@ class OpenHABWidget: NSObject, MKAnnotation { // Text between square brackets var labelValue: String? { - // Swift 5 raw strings let regex = try? NSRegularExpression(pattern: #"\[(.*?)\]"#, options: []) guard let match = regex?.firstMatch(in: label, options: [], range: NSRange(location: 0, length: (label as NSString).length)) else { return nil } guard let range = Range(match.range(at: 1), in: label) else { return nil } return String(label[range]) - } var coordinate: CLLocationCoordinate2D { @@ -85,15 +83,12 @@ class OpenHABWidget: NSObject, MKAnnotation { } return nil } - } extension OpenHABWidget { - // This is an ugly initializer - convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABLinkedPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget] ) { - - func toString (_ with: Double?) -> String { + convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABLinkedPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget]) { + func toString(_ with: Double?) -> String { guard let double = with else { return "" } return String(format: "%.1f", double) } @@ -116,8 +111,8 @@ extension OpenHABWidget { self.height = toString(height) self.isLeaf = isLeaf ?? false self.iconColor = iconColor ?? "" - self.labelcolor = labelColor ?? "" - self.valuecolor = valueColor ?? "" + labelcolor = labelColor ?? "" + valuecolor = valueColor ?? "" self.service = service ?? "" self.state = state ?? "" self.text = text ?? "" @@ -160,7 +155,7 @@ extension OpenHABWidget { case "legend": legend = child.stringValue == "true" ? true : false // Int case "refresh": refresh = Int(child.stringValue) ?? 0 - // Embedded + // Embedded case "widget": widgets.append(OpenHABWidget(xml: child)) case "item": item = OpenHABItem(xml: child) case "mapping": mappings.append(OpenHABWidgetMapping(xml: child)) @@ -205,8 +200,8 @@ extension OpenHABWidget { // swiftlint:disable line_length extension OpenHABWidget.CodingData { var openHABWidget: OpenHABWidget { - let mappedWidgets = self.widgets.map { $0.openHABWidget } - return OpenHABWidget(widgetId: self.widgetId, label: self.label, icon: self.icon, type: self.type, url: self.url, period: self.period, minValue: self.minValue, maxValue: self.maxValue, step: self.step, refresh: self.refresh, height: self.height, isLeaf: self.isLeaf, iconColor: self.iconColor, labelColor: self.labelcolor, valueColor: self.valuecolor, service: self.service, state: self.state, text: self.text, legend: self.legend, encoding: self.encoding, item: self.item?.openHABItem, linkedPage: self.linkedPage, mappings: self.mappings, widgets: mappedWidgets) + let mappedWidgets = widgets.map { $0.openHABWidget } + return OpenHABWidget(widgetId: widgetId, label: label, icon: icon, type: type, url: url, period: period, minValue: minValue, maxValue: maxValue, step: step, refresh: refresh, height: height, isLeaf: isLeaf, iconColor: iconColor, labelColor: labelcolor, valueColor: valuecolor, service: service, state: state, text: text, legend: legend, encoding: encoding, item: item?.openHABItem, linkedPage: linkedPage, mappings: mappings, widgets: mappedWidgets) } } @@ -214,8 +209,8 @@ extension OpenHABWidget.CodingData { extension Array where Element == OpenHABWidget { mutating func flatten(_ widgets: [Element]) { for widget in widgets { - self.append(widget) - self.flatten(widget.widgets) + append(widget) + flatten(widget.widgets) } } } diff --git a/openHAB/PlayerView.swift b/openHAB/PlayerView.swift index 8b6be8daa..37a744294 100644 --- a/openHAB/PlayerView.swift +++ b/openHAB/PlayerView.swift @@ -13,7 +13,6 @@ import AVFoundation import AVKit class PlayerView: UIView { - // Override UIView property override static var layerClass: AnyClass { return AVPlayerLayer.self diff --git a/openHAB/Reachability+URL.swift b/openHAB/Reachability+URL.swift index bf327b74a..d86908d6d 100644 --- a/openHAB/Reachability+URL.swift +++ b/openHAB/Reachability+URL.swift @@ -14,7 +14,7 @@ extension Reachability { } convenience init(url: URL?) { - self.withHostName(url?.host) + withHostName(url?.host) } func currentlyReachable() -> Bool { diff --git a/openHAB/Reachability.swift b/openHAB/Reachability.swift index 435dd9fb3..761e7ed07 100644 --- a/openHAB/Reachability.swift +++ b/openHAB/Reachability.swift @@ -46,7 +46,6 @@ public extension Notification.Name { } public class Reachability { - public typealias NetworkReachable = (Reachability) -> Void public typealias NetworkUnreachable = (Reachability) -> Void @@ -107,7 +106,7 @@ public class Reachability { } } - fileprivate var isRunningOnDevice: Bool = { + private var isRunningOnDevice: Bool = { #if targetEnvironment(simulator) return false #else @@ -115,9 +114,9 @@ public class Reachability { #endif }() - fileprivate var notifierRunning = false - fileprivate let reachabilityRef: SCNetworkReachability - fileprivate let reachabilitySerialQueue: DispatchQueue + private var notifierRunning = false + private let reachabilityRef: SCNetworkReachability + private let reachabilitySerialQueue: DispatchQueue fileprivate(set) var flags: SCNetworkReachabilityFlags? { didSet { guard flags != oldValue else { return } @@ -126,9 +125,9 @@ public class Reachability { } required public init(reachabilityRef: SCNetworkReachability, queueQoS: DispatchQoS = .default, targetQueue: DispatchQueue? = nil) { - self.allowsCellularConnection = true + allowsCellularConnection = true self.reachabilityRef = reachabilityRef - self.reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability", qos: queueQoS, target: targetQueue) + reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability", qos: queueQoS, target: targetQueue) } public convenience init?(hostname: String, queueQoS: DispatchQoS = .default, targetQueue: DispatchQueue? = nil) { @@ -152,12 +151,12 @@ public class Reachability { } public extension Reachability { - // MARK: - *** Notifier methods *** + func startNotifier() throws { guard !notifierRunning else { return } - let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in + let callback: SCNetworkReachabilityCallBack = { reachability, flags, info in guard let info = info else { return } let reachability = Unmanaged.fromOpaque(info).takeUnretainedValue() @@ -190,6 +189,7 @@ public extension Reachability { } // MARK: - *** Connection test methods *** + @available(*, deprecated, message: "Please use `connection != .none`") var isReachable: Bool { return connection != .none @@ -222,8 +222,7 @@ public extension Reachability { } } -fileprivate extension Reachability { - +private extension Reachability { func setReachabilityFlags() throws { try reachabilitySerialQueue.sync { [unowned self] in var flags = SCNetworkReachabilityFlags() @@ -248,7 +247,6 @@ fileprivate extension Reachability { } extension SCNetworkReachabilityFlags { - typealias Connection = Reachability.Connection var connection: Connection { @@ -285,33 +283,43 @@ extension SCNetworkReachabilityFlags { return false #endif } + var isReachableFlagSet: Bool { return contains(.reachable) } + var isConnectionRequiredFlagSet: Bool { return contains(.connectionRequired) } + var isInterventionRequiredFlagSet: Bool { return contains(.interventionRequired) } + var isConnectionOnTrafficFlagSet: Bool { return contains(.connectionOnTraffic) } + var isConnectionOnDemandFlagSet: Bool { return contains(.connectionOnDemand) } + var isConnectionOnTrafficOrDemandFlagSet: Bool { return !intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty } + var isTransientConnectionFlagSet: Bool { return contains(.transientConnection) } + var isLocalAddressFlagSet: Bool { return contains(.isLocalAddress) } + var isDirectFlagSet: Bool { return contains(.isDirect) } + var isConnectionRequiredAndTransientFlagSet: Bool { return intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection] } diff --git a/openHAB/ReusableView.swift b/openHAB/ReusableView.swift index ce4b2995b..b6122a6bf 100644 --- a/openHAB/ReusableView.swift +++ b/openHAB/ReusableView.swift @@ -10,19 +10,13 @@ import Foundation import UIKit protocol ReusableView { - static var reuseIdentifier: String { get } - } extension ReusableView { - static var reuseIdentifier: String { return String(describing: self) } - } -extension UITableViewCell: ReusableView { - -} +extension UITableViewCell: ReusableView {} diff --git a/openHAB/RollershutterUITableViewCell.swift b/openHAB/RollershutterUITableViewCell.swift index 319f55a12..f42331709 100644 --- a/openHAB/RollershutterUITableViewCell.swift +++ b/openHAB/RollershutterUITableViewCell.swift @@ -12,17 +12,15 @@ import DynamicButton import os.log class RollershutterUITableViewCell: GenericUITableViewCell { + @IBOutlet private var downButton: DynamicButton! + @IBOutlet private var stopButton: DynamicButton! + @IBOutlet private var upButton: DynamicButton! - @IBOutlet weak var downButton: DynamicButton! - @IBOutlet weak var stopButton: DynamicButton! - @IBOutlet weak var upButton: DynamicButton! - - @IBOutlet weak var customDetailText: UILabel! + @IBOutlet private var customDetailText: UILabel! override func initialize() { selectionStyle = .none separatorInset = .zero - } required init?(coder: NSCoder) { @@ -31,7 +29,7 @@ class RollershutterUITableViewCell: GenericUITableViewCell { initialize() } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { os_log("RollershutterUITableViewCell initWithStyle", log: .viewCycle, type: .info) super.init(style: style, reuseIdentifier: reuseIdentifier) initialize() @@ -47,8 +45,8 @@ class RollershutterUITableViewCell: GenericUITableViewCell { stopButton?.addTarget(self, action: .stopButtonPressed, for: .touchUpInside) downButton?.addTarget(self, action: .downButtonPressed, for: .touchUpInside) downButton?.highlightStokeColor = Colors.hightlightStrokeColor - upButton?.highlightStokeColor = Colors.hightlightStrokeColor - stopButton?.highlightStokeColor = Colors.hightlightStrokeColor + upButton?.highlightStokeColor = Colors.hightlightStrokeColor + stopButton?.highlightStokeColor = Colors.hightlightStrokeColor } @objc @@ -72,7 +70,7 @@ class RollershutterUITableViewCell: GenericUITableViewCell { // inspired by: Selectors in swift: A better approach using extensions // https://medium.com/@abhimuralidharan/selectors-in-swift-a-better-approach-using-extensions-aa6b0416e850 -fileprivate extension Selector { +private extension Selector { static let upButtonPressed = #selector(RollershutterUITableViewCell.upButtonPressed) static let stopButtonPressed = #selector(RollershutterUITableViewCell.stopButtonPressed) static let downButtonPressed = #selector(RollershutterUITableViewCell.downButtonPressed) diff --git a/openHAB/ScaleAspectFitImageView.swift b/openHAB/ScaleAspectFitImageView.swift index a3dce9b43..a224782e2 100644 --- a/openHAB/ScaleAspectFitImageView.swift +++ b/openHAB/ScaleAspectFitImageView.swift @@ -18,46 +18,46 @@ public class ScaleAspectFitImageView: UIImageView { required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - self.setup() + setup() } public override init(frame: CGRect) { super.init(frame: frame) - self.setup() + setup() } public override init(image: UIImage!) { super.init(image: image) - self.setup() + setup() } public override init(image: UIImage!, highlightedImage: UIImage?) { super.init(image: image, highlightedImage: highlightedImage) - self.setup() + setup() } private func setup() { - self.contentMode = .scaleAspectFit - self.updateAspectRatioConstraint() + contentMode = .scaleAspectFit + updateAspectRatioConstraint() } /// Removes any pre-existing aspect ratio constraint, and adds a new one based on the current image private func updateAspectRatioConstraint() { if let constraint = self.aspectRatioConstraint { - self.removeConstraint(constraint) + removeConstraint(constraint) } - self.aspectRatioConstraint = nil + aspectRatioConstraint = nil if let imageSize = image?.size, imageSize.height != 0 { let aspectRatio = imageSize.width / imageSize.height let constraint = NSLayoutConstraint(item: self, attribute: .width, - relatedBy: .equal, - toItem: self, attribute: .height, - multiplier: aspectRatio, constant: 0) + relatedBy: .equal, + toItem: self, attribute: .height, + multiplier: aspectRatio, constant: 0) constraint.priority = UILayoutPriority(rawValue: 999) - self.addConstraint(constraint) - self.aspectRatioConstraint = constraint + addConstraint(constraint) + aspectRatioConstraint = constraint } } } diff --git a/openHAB/ScaledHeightUIImageView.swift b/openHAB/ScaledHeightUIImageView.swift index 1e0b030ad..8e84d0701 100644 --- a/openHAB/ScaledHeightUIImageView.swift +++ b/openHAB/ScaledHeightUIImageView.swift @@ -9,7 +9,6 @@ /// An image view that computes its intrinsic height from its width while preserving aspect ratio /// Source: https://stackoverflow.com/a/48476446 class ScaledHeightUIImageView: UIImageView { - // Track the width that the intrinsic size was computed for, // to invalidate the intrinsic size when needed private var layoutedWidth: CGFloat = 0 diff --git a/openHAB/SegmentedUITableViewCell.swift b/openHAB/SegmentedUITableViewCell.swift index b12244ed6..acce1ac54 100644 --- a/openHAB/SegmentedUITableViewCell.swift +++ b/openHAB/SegmentedUITableViewCell.swift @@ -11,23 +11,20 @@ import os.log import UIKit class SegmentedUITableViewCell: GenericUITableViewCell { - - //@IBOutlet weak var customTextLabel: UILabel! - @IBOutlet weak var widgetSegmentControl: UISegmentedControl! + // @IBOutlet private var customTextLabel: UILabel! + @IBOutlet private var widgetSegmentControl: UISegmentedControl! required init?(coder: NSCoder) { super.init(coder: coder) selectionStyle = .none separatorInset = .zero - } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) selectionStyle = .none separatorInset = .zero - } override func displayWidget() { @@ -39,7 +36,7 @@ class SegmentedUITableViewCell: GenericUITableViewCell { widgetSegmentControl?.apportionsSegmentWidthsByContent = true for mapping in widget?.mappings ?? [] { - widgetSegmentControl?.insertSegment(withTitle: mapping.label, at: widget.mappings.firstIndex(of: mapping)!, animated: false) + widgetSegmentControl?.insertSegment(withTitle: mapping.label, at: widget.mappings.firstIndex(of: mapping)!, animated: false) } widgetSegmentControl?.selectedSegmentIndex = Int(widget.mappingIndex(byCommand: widget.item?.state) ?? -1) diff --git a/openHAB/SelectionUITableViewCell.swift b/openHAB/SelectionUITableViewCell.swift index 7d910f184..f5a9b3e15 100644 --- a/openHAB/SelectionUITableViewCell.swift +++ b/openHAB/SelectionUITableViewCell.swift @@ -9,7 +9,6 @@ // class SelectionUITableViewCell: GenericUITableViewCell { - override var widget: OpenHABWidget! { get { return super.widget diff --git a/openHAB/ServerCertificateManager.swift b/openHAB/ServerCertificateManager.swift index ba75a30c6..62ee93d87 100644 --- a/openHAB/ServerCertificateManager.swift +++ b/openHAB/ServerCertificateManager.swift @@ -25,6 +25,7 @@ class ServerCertificateManager { case permitOnce case permitAlways } + var evaluateResult: EvaluateResult = .undecided weak var delegate: ServerCertificateManagerDelegate? var allowInvalidCertificates: Bool = false @@ -37,12 +38,12 @@ class ServerCertificateManager { func initializeCertificatesStore() { os_log("Initializing cert store", log: .remoteAccess, type: .info) - self.loadTrustedCertificates() + loadTrustedCertificates() if trustedCertificates.isEmpty { os_log("No cert store, creating", log: .remoteAccess, type: .info) trustedCertificates = [:] // [trustedCertificates setObject:@"Bulk" forKey:@"Bulk id to make it non-empty"]; - self.saveTrustedCertificates() + saveTrustedCertificates() } else { os_log("Loaded existing cert store", log: .remoteAccess, type: .info) } @@ -58,7 +59,7 @@ class ServerCertificateManager { func saveTrustedCertificates() { do { let data = try NSKeyedArchiver.archivedData(withRootObject: trustedCertificates, requiringSecureCoding: false) - try data.write(to: URL(string: self.getPersistensePath() ?? "")!) + try data.write(to: URL(string: getPersistensePath() ?? "")!) } catch { os_log("Could not save trusted certificates", log: .default) } @@ -67,7 +68,7 @@ class ServerCertificateManager { func storeCertificateData(_ certificate: CFData?, forDomain domain: String) { let certificateData = certificate as Data? trustedCertificates[domain] = certificateData - self.saveTrustedCertificates() + saveTrustedCertificates() } func certificateData(forDomain domain: String) -> CFData? { @@ -77,7 +78,7 @@ class ServerCertificateManager { func loadTrustedCertificates() { do { - let rawdata = try Data(contentsOf: URL( string: self.getPersistensePath() ?? "" )!) + let rawdata = try Data(contentsOf: URL(string: getPersistensePath() ?? "")!) if let unarchive = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(rawdata) as? [String: Any] { trustedCertificates = unarchive } @@ -88,7 +89,7 @@ class ServerCertificateManager { func evaluateTrust(challenge: URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?) { let serverTrust = challenge.protectionSpace.serverTrust! - if self.evaluateServerTrust(serverTrust, forDomain: challenge.protectionSpace.host) { + if evaluateServerTrust(serverTrust, forDomain: challenge.protectionSpace.host) { let credential = URLCredential(trust: serverTrust) return (.useCredential, credential) } @@ -134,7 +135,7 @@ class ServerCertificateManager { case .permitAlways: // User decided to accept invalid certificate and remember decision // Add certificate to storage - self.storeCertificateData(certificateData, forDomain: domain) + storeCertificateData(certificateData, forDomain: domain) return true case .undecided: // Something went wrong, abort connection @@ -163,7 +164,7 @@ class ServerCertificateManager { case .permitAlways: // User decided to accept invalid certificate and remember decision // Add certificate to storage - self.storeCertificateData(certificateData, forDomain: domain) + storeCertificateData(certificateData, forDomain: domain) return true case .undecided: return false @@ -188,6 +189,5 @@ class ServerCertificateManager { } else { return nil } - } } diff --git a/openHAB/SetpointUITableViewCell.swift b/openHAB/SetpointUITableViewCell.swift index 0d318cb61..a1436d18d 100644 --- a/openHAB/SetpointUITableViewCell.swift +++ b/openHAB/SetpointUITableViewCell.swift @@ -11,7 +11,6 @@ import DynamicButton import os.log class SetpointUITableViewCell: GenericUITableViewCell { - private var isIntStep: Bool { return widget.step.truncatingRemainder(dividingBy: 1) == 0 } @@ -20,15 +19,14 @@ class SetpointUITableViewCell: GenericUITableViewCell { return isIntStep ? "%ld" : "%.01f" } - @IBOutlet weak var downButton: DynamicButton! - @IBOutlet weak var upButton: DynamicButton! + @IBOutlet private var downButton: DynamicButton! + @IBOutlet private var upButton: DynamicButton! required init?(coder: NSCoder) { super.init(coder: coder) selectionStyle = .none separatorInset = .zero - } override func displayWidget() { @@ -39,7 +37,7 @@ class SetpointUITableViewCell: GenericUITableViewCell { upButton.addTarget(self, action: #selector(SetpointUITableViewCell.increaseValue), for: .touchUpInside) downButton.highlightStokeColor = Colors.hightlightStrokeColor - upButton.highlightStokeColor = Colors.hightlightStrokeColor + upButton.highlightStokeColor = Colors.hightlightStrokeColor super.displayWidget() } diff --git a/openHAB/SliderUITableViewCell.swift b/openHAB/SliderUITableViewCell.swift index 53ca27d13..e7acccf09 100644 --- a/openHAB/SliderUITableViewCell.swift +++ b/openHAB/SliderUITableViewCell.swift @@ -12,19 +12,18 @@ import os.log import UIKit class SliderUITableViewCell: GenericUITableViewCell { + @IBOutlet private var widgetSlider: UISlider! - @IBOutlet weak var widgetSlider: UISlider! - - @IBOutlet weak var customDetailText: UILabel! + @IBOutlet private var customDetailText: UILabel! required init?(coder: NSCoder) { super.init(coder: coder) - self.initiliaze() + initiliaze() } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - self.initiliaze() + initiliaze() } private func initiliaze() { @@ -33,7 +32,7 @@ class SliderUITableViewCell: GenericUITableViewCell { } @IBAction func sliderValueChanged(_ sender: Any) { - let widgetValue = adj(Double(widgetSlider?.value ?? Float (widget.minValue))) + let widgetValue = adj(Double(widgetSlider?.value ?? Float(widget.minValue))) customDetailText?.text = valueText(widgetValue) } @@ -60,10 +59,10 @@ class SliderUITableViewCell: GenericUITableViewCell { } func valueText(_ widgetValue: Double) -> String { - let digits = max (-Decimal(widget.step).exponent, 0) + let digits = max(-Decimal(widget.step).exponent, 0) let numberFormatter = NumberFormatter() numberFormatter.maximumFractionDigits = digits - numberFormatter.decimalSeparator = "." + numberFormatter.decimalSeparator = "." return numberFormatter.string(from: NSNumber(value: widgetValue)) ?? "" } @@ -77,7 +76,7 @@ class SliderUITableViewCell: GenericUITableViewCell { } @objc - func sliderDidEndSliding (_ sender: UISlider) { + func sliderDidEndSliding(_ sender: UISlider) { let res = adj(Double(widgetSlider!.value)) os_log("Slider new value = %g, adjusted to %g", log: .default, type: .info, widgetSlider!.value, res) widget.sendCommand(valueText(res)) diff --git a/openHAB/StringExtension.swift b/openHAB/StringExtension.swift index d011afa94..4d04e67ea 100644 --- a/openHAB/StringExtension.swift +++ b/openHAB/StringExtension.swift @@ -9,7 +9,6 @@ import Foundation extension String { - var doubleValue: Double { let formatter = NumberFormatter() formatter.decimalSeparator = "." @@ -37,6 +36,6 @@ extension String { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.decimalSeparator = "." - return formatter.number(from: self.filter("01234567890.-".contains)) + return formatter.number(from: filter("01234567890.-".contains)) } } diff --git a/openHAB/SwitchUITableViewCell.swift b/openHAB/SwitchUITableViewCell.swift index 6cdd6515c..21aa4a535 100644 --- a/openHAB/SwitchUITableViewCell.swift +++ b/openHAB/SwitchUITableViewCell.swift @@ -11,8 +11,7 @@ import os.log import UIKit class SwitchUITableViewCell: GenericUITableViewCell { - - @IBOutlet var widgetSwitch: UISwitch! + @IBOutlet private var widgetSwitch: UISwitch! override func initialize() { selectionStyle = .none @@ -21,22 +20,22 @@ class SwitchUITableViewCell: GenericUITableViewCell { required init?(coder: NSCoder) { super.init(coder: coder) - self.initialize() + initialize() } - override init (style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - self.initialize() + initialize() } override func displayWidget() { - self.customTextLabel?.text = widget.labelText + customTextLabel?.text = widget.labelText var state = widget.state // if state is nil or empty using the item state ( OH 1.x compatability ) if state.isEmpty { state = (widget.item?.state) ?? "" } - self.customDetailTextLabel?.text = widget.labelValue ?? "" + customDetailTextLabel?.text = widget.labelValue ?? "" widgetSwitch?.isOn = (state == "ON" ? true : false) widgetSwitch?.addTarget(self, action: .switchChange, for: .valueChanged) super.displayWidget() @@ -54,6 +53,6 @@ class SwitchUITableViewCell: GenericUITableViewCell { } } -fileprivate extension Selector { +private extension Selector { static let switchChange = #selector(SwitchUITableViewCell.switchChange) } diff --git a/openHAB/UIAlertView+Block.swift b/openHAB/UIAlertView+Block.swift index 78b80c4a0..d8ba6175a 100644 --- a/openHAB/UIAlertView+Block.swift +++ b/openHAB/UIAlertView+Block.swift @@ -16,7 +16,7 @@ private var kNSCBAlertWrapper = 0 class NSCBAlertWrapper: NSObject { var completionBlock: ((_ alertView: UIAlertView?, _ buttonIndex: Int) -> Void)? -// MARK: - UIAlertViewDelegate + // MARK: - UIAlertViewDelegate // Called when a button is clicked. The view will be automatically dismissed after this call returns func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) { diff --git a/openHAB/UICircleButton.swift b/openHAB/UICircleButton.swift index ae68f7ddf..215fc5998 100644 --- a/openHAB/UICircleButton.swift +++ b/openHAB/UICircleButton.swift @@ -19,7 +19,7 @@ class UICircleButton: UIButton { super.init(coder: coder) layer.borderWidth = 2 - layer.borderColor = UIColor.init(white: 0, alpha: 0.05).cgColor + layer.borderColor = UIColor(white: 0, alpha: 0.05).cgColor layer.cornerRadius = bounds.size.width / 2.0 } diff --git a/openHAB/UITableView.swift b/openHAB/UITableView.swift index 6160fafec..e654c6aa6 100644 --- a/openHAB/UITableView.swift +++ b/openHAB/UITableView.swift @@ -9,16 +9,14 @@ import UIKit extension UITableView { - final func dequeueReusableCell(for indexPath: IndexPath, cellType: T.Type = T.self) -> T { - guard let cell = self.dequeueReusableCell(withIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { - fatalError("Unable to Dequeue Reusable Table View Cell") - } - return cell + guard let cell = self.dequeueReusableCell(withIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { + fatalError("Unable to Dequeue Reusable Table View Cell") + } + return cell } final func register(cellType: T.Type) { - self.register(cellType.self, forCellReuseIdentifier: cellType.reuseIdentifier) + register(cellType.self, forCellReuseIdentifier: cellType.reuseIdentifier) } - } diff --git a/openHAB/VideoUITableViewCell.swift b/openHAB/VideoUITableViewCell.swift index d34134ea3..79a540b45 100644 --- a/openHAB/VideoUITableViewCell.swift +++ b/openHAB/VideoUITableViewCell.swift @@ -18,7 +18,6 @@ enum VideoEncoding: String { } class VideoUITableViewCell: GenericUITableViewCell { - private let activityIndicator = UIActivityIndicatorView(style: .gray) var didLoad: (() -> Void)? @@ -29,6 +28,7 @@ class VideoUITableViewCell: GenericUITableViewCell { prepareToPlay() } } + private var playerView: PlayerView! private var mainImageView: UIImageView! private var playerObserver: NSKeyValueObservation? @@ -53,30 +53,24 @@ class VideoUITableViewCell: GenericUITableViewCell { playerView.translatesAutoresizingMaskIntoConstraints = false // enable autolayout playerView.contentMode = .scaleAspectFit - let marginGuide = contentView //contentView.layoutMarginsGuide if more margin would be appreciated - NSLayoutConstraint.activate([ - playerView.leftAnchor.constraint(equalTo: marginGuide.leftAnchor), - playerView.rightAnchor.constraint(equalTo: marginGuide.rightAnchor), - playerView.topAnchor.constraint(equalTo: marginGuide.topAnchor), - playerView.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor) - ]) + let marginGuide = contentView // contentView.layoutMarginsGuide if more margin would be appreciated + NSLayoutConstraint.activate([playerView.leftAnchor.constraint(equalTo: marginGuide.leftAnchor), + playerView.rightAnchor.constraint(equalTo: marginGuide.rightAnchor), + playerView.topAnchor.constraint(equalTo: marginGuide.topAnchor), + playerView.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor)]) mainImageView.translatesAutoresizingMaskIntoConstraints = false // enable autolayout - NSLayoutConstraint.activate([ - mainImageView.leftAnchor.constraint(equalTo: marginGuide.leftAnchor), - mainImageView.rightAnchor.constraint(equalTo: marginGuide.rightAnchor), - mainImageView.topAnchor.constraint(equalTo: marginGuide.topAnchor), - mainImageView.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor) - ]) + NSLayoutConstraint.activate([mainImageView.leftAnchor.constraint(equalTo: marginGuide.leftAnchor), + mainImageView.rightAnchor.constraint(equalTo: marginGuide.rightAnchor), + mainImageView.topAnchor.constraint(equalTo: marginGuide.topAnchor), + mainImageView.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor)]) let bottomSpacingConstraint = activityIndicator.bottomAnchor.constraint(greaterThanOrEqualTo: marginGuide.bottomAnchor, constant: 15) bottomSpacingConstraint.priority = UILayoutPriority.defaultHigh - NSLayoutConstraint.activate([ - activityIndicator.centerXAnchor.constraint(equalTo: marginGuide.centerXAnchor), - activityIndicator.centerYAnchor.constraint(equalTo: marginGuide.centerYAnchor), - activityIndicator.topAnchor.constraint(greaterThanOrEqualTo: marginGuide.topAnchor, constant: 15), - bottomSpacingConstraint - ]) + NSLayoutConstraint.activate([activityIndicator.centerXAnchor.constraint(equalTo: marginGuide.centerXAnchor), + activityIndicator.centerYAnchor.constraint(equalTo: marginGuide.centerYAnchor), + activityIndicator.topAnchor.constraint(greaterThanOrEqualTo: marginGuide.topAnchor, constant: 15), + bottomSpacingConstraint]) NotificationCenter.default.addObserver(self, selector: #selector(stopPlayback), name: UIApplication.didEnterBackgroundNotification, object: nil) } @@ -120,7 +114,7 @@ class VideoUITableViewCell: GenericUITableViewCell { if widget.encoding.lowercased() != VideoEncoding.mjpeg.rawValue { bringSubviewToFront(playerView) let playerItem = AVPlayerItem(asset: AVAsset(url: url)) - playerObserver = playerItem.observe(\.status, options: [.new, .old]) { [weak self] (playerItem, _) in + playerObserver = playerItem.observe(\.status, options: [.new, .old]) { [weak self] playerItem, _ in switch playerItem.status { case .failed: os_log("Failed to load video with URL: %{PUBLIC}@", log: .urlComposition, type: .debug, url.absoluteString) @@ -159,8 +153,8 @@ class VideoUITableViewCell: GenericUITableViewCell { let streamImageInitialBytePattern = Data([255, 216]) var imageData = Data() mjpegRequest = NetworkConnection.shared.manager.request(streamRequest) - .validate(statusCode: 200..<300) - .stream { [weak self] (chunkData) in + .validate(statusCode: 200 ..< 300) + .stream { [weak self] chunkData in if chunkData.starts(with: streamImageInitialBytePattern) { if let image = UIImage(data: imageData) { DispatchQueue.main.async { @@ -209,7 +203,7 @@ class VideoUITableViewCell: GenericUITableViewCell { playerView?.playerLayer.player = nil mjpegRequest?.cancel() mjpegRequest = nil - self.mainImageView?.image = nil + mainImageView?.image = nil } } diff --git a/openHAB/WatchMessageService.swift b/openHAB/WatchMessageService.swift index 3bf5b07f5..7e488b011 100644 --- a/openHAB/WatchMessageService.swift +++ b/openHAB/WatchMessageService.swift @@ -12,13 +12,11 @@ import WatchConnectivity // This class receives Watch Request for the configuration data like localUrl. // The functionality is activated in the AppDelegate. class WatchMessageService: NSObject, WCSessionDelegate { - static let singleton = WatchMessageService() // This method gets called when the watch requests the localUrl func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) { - - // TODO Use RemoteUrl, TOO + // TODO: Use RemoteUrl, TOO if message["requestLocalUrl"] != nil { replyHandler(["baseUri": Preferences.localUrl]) } @@ -29,12 +27,9 @@ class WatchMessageService: NSObject, WCSessionDelegate { } @available(iOS 9.3, *) - func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { - } + func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {} - func sessionDidBecomeInactive(_ session: WCSession) { - } + func sessionDidBecomeInactive(_ session: WCSession) {} - func sessionDidDeactivate(_ session: WCSession) { - } + func sessionDidDeactivate(_ session: WCSession) {} } diff --git a/openHAB/WatchService.swift b/openHAB/WatchService.swift index 71f7913f9..11c4100bc 100644 --- a/openHAB/WatchService.swift +++ b/openHAB/WatchService.swift @@ -10,7 +10,6 @@ import Foundation import WatchConnectivity class WatchService { - static let singleton = WatchService() private var lastWatchUpdateTime: Date? @@ -19,7 +18,6 @@ class WatchService { // swiftlint:disable:next function_parameter_count func sendToWatch(_ localUrl: String, remoteUrl: String, username: String, password: String, sitemapName: String, ignoreSSL: Bool) { - let applicationDict: [String: Any] = ["localUrl": localUrl, "remoteUrl": remoteUrl, @@ -32,7 +30,6 @@ class WatchService { } private func sendOrTransmitToWatch(_ message: [String: Any]) { - // send message if watch is reachable if WCSession.default.isReachable { WCSession.default.sendMessage(message, replyHandler: { data in @@ -44,7 +41,6 @@ class WatchService { try? WCSession.default.updateApplicationContext(message) }) } else { - // otherwise, transmit application context try? WCSession.default.updateApplicationContext(message) } diff --git a/openHAB/WebUITableViewCell.swift b/openHAB/WebUITableViewCell.swift index d69c23083..89122cc71 100644 --- a/openHAB/WebUITableViewCell.swift +++ b/openHAB/WebUITableViewCell.swift @@ -14,7 +14,7 @@ import WebKit class WebUITableViewCell: GenericUITableViewCell { private var url: URL? - @IBOutlet weak var widgetWebView: WKWebView! + @IBOutlet private var widgetWebView: WKWebView! required init?(coder: NSCoder) { super.init(coder: coder) diff --git a/openHABTestsSwift/MockURLProtocol.swift b/openHABTestsSwift/MockURLProtocol.swift index b6b6a38aa..4454037d0 100644 --- a/openHABTestsSwift/MockURLProtocol.swift +++ b/openHABTestsSwift/MockURLProtocol.swift @@ -9,7 +9,6 @@ import Foundation final class MockURLProtocol: URLProtocol { - enum ResponseType { case error(Error) case success(HTTPURLResponse) @@ -44,22 +43,20 @@ final class MockURLProtocol: URLProtocol { override func stopLoading() { activeTask?.cancel() } - } // MARK: - URLSessionDataDelegate extension MockURLProtocol: URLSessionDataDelegate { - func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { client?.urlProtocol(self, didLoad: data) } func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { switch MockURLProtocol.responseType { - case .error(let error)?: + case let .error(error)?: client?.urlProtocol(self, didFailWithError: error) - case .success(let response)?: + case let .success(response)?: client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) default: break @@ -70,7 +67,6 @@ extension MockURLProtocol: URLSessionDataDelegate { } extension MockURLProtocol { - enum MockError: Error { case none } diff --git a/openHABTestsSwift/OpenHABGeneralTests.swift b/openHABTestsSwift/OpenHABGeneralTests.swift index c84d09254..c73df9a6c 100644 --- a/openHABTestsSwift/OpenHABGeneralTests.swift +++ b/openHABTestsSwift/OpenHABGeneralTests.swift @@ -9,7 +9,6 @@ import XCTest class OpenHABGeneralTests: XCTestCase { - override func setUp() { super.setUp() } @@ -21,22 +20,21 @@ class OpenHABGeneralTests: XCTestCase { func testValueToText() { func valueText(_ widgetValue: Double, step: Double) -> String { - let digits = max (-Decimal(step).exponent, 0) + let digits = max(-Decimal(step).exponent, 0) let numberFormatter = NumberFormatter() numberFormatter.minimumFractionDigits = digits - numberFormatter.decimalSeparator = "." + numberFormatter.decimalSeparator = "." return numberFormatter.string(from: NSNumber(value: widgetValue)) ?? "" } func valueTextWithoutFormatter(_ widgetValue: Double, step: Double) -> String { - let digits = max (-Decimal(step).exponent, 0) + let digits = max(-Decimal(step).exponent, 0) return String(format: "%.\(digits)f", widgetValue) } XCTAssertEqual(valueText(1000.0, step: 5.23), "1000.00") XCTAssertEqual(valueText(1000.0, step: 1), "1000") XCTAssertEqual(valueTextWithoutFormatter(1000.0, step: 5.23), "1000.00") - } func testHexString() { @@ -50,7 +48,7 @@ class OpenHABGeneralTests: XCTestCase { version: 2, icon: "switch", value: "OFF", - iconType: .svg ).url + iconType: .svg).url XCTAssertEqual(urlc, URL(string: "http://192.169.2.1/icon/switch?state=OFF&format=SVG"), "Check endpoint creation") } diff --git a/openHABTestsSwift/OpenHABJSONParserTests.swift b/openHABTestsSwift/OpenHABJSONParserTests.swift index 36b2c5b14..d827dab6f 100644 --- a/openHABTestsSwift/OpenHABJSONParserTests.swift +++ b/openHABTestsSwift/OpenHABJSONParserTests.swift @@ -10,7 +10,6 @@ import os.signpost import XCTest class OpenHABJSONParserTests: XCTestCase { - let decoder = JSONDecoder() override func setUp() { @@ -28,11 +27,11 @@ class OpenHABJSONParserTests: XCTestCase { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. - //[{"_id":"5c4229b41cd87d98382869da","message":"Light Küche was changed","__v":0,"created":"2019-01-18T19:32:04.648Z"}, + // [{"_id":"5c4229b41cd87d98382869da","message":"Light Küche was changed","__v":0,"created":"2019-01-18T19:32:04.648Z"}, // swiftlint:disable line_length let json = """ - [{"_id":"5c82e14d2b48ecbf7a7223e0","message":"Light Küche was changed","__v":0,"created":"2019-03-08T21:40:29.412Z"},{"_id":"5c82c9c22b48ecbf7a70f44e","message":"Light Küche was changed","__v":0,"created":"2019-03-08T20:00:02.368Z"},{"_id":"5c82c9c02b48ecbf7a70f42c","message":"Light Küche was changed","__v":0,"created":"2019-03-08T20:00:00.982Z"},{"_id":"5c7fff782b48ecbf7a4dd8e4","message":"Light Küche was changed","__v":0,"created":"2019-03-06T17:12:24.093Z"},{"_id":"5c7ff5c12b48ecbf7a4d56fb","message":"Light Küche was changed","__v":0,"created":"2019-03-06T16:30:57.101Z"},{"_id":"5c7ed0852b48ecbf7a3d2151","message":"Light Küche was changed","__v":0,"created":"2019-03-05T19:39:49.373Z"},{"_id":"5c7d50ba2b48ecbf7a26948f","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:18.473Z"},{"_id":"5c7d50b62b48ecbf7a269455","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:14.321Z"},{"_id":"5c7d50b42b48ecbf7a269442","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:12.468Z"},{"_id":"5c7d507d2b48ecbf7a26916c","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:21:17.006Z"}] -""".data(using: .utf8)! + [{"_id":"5c82e14d2b48ecbf7a7223e0","message":"Light Küche was changed","__v":0,"created":"2019-03-08T21:40:29.412Z"},{"_id":"5c82c9c22b48ecbf7a70f44e","message":"Light Küche was changed","__v":0,"created":"2019-03-08T20:00:02.368Z"},{"_id":"5c82c9c02b48ecbf7a70f42c","message":"Light Küche was changed","__v":0,"created":"2019-03-08T20:00:00.982Z"},{"_id":"5c7fff782b48ecbf7a4dd8e4","message":"Light Küche was changed","__v":0,"created":"2019-03-06T17:12:24.093Z"},{"_id":"5c7ff5c12b48ecbf7a4d56fb","message":"Light Küche was changed","__v":0,"created":"2019-03-06T16:30:57.101Z"},{"_id":"5c7ed0852b48ecbf7a3d2151","message":"Light Küche was changed","__v":0,"created":"2019-03-05T19:39:49.373Z"},{"_id":"5c7d50ba2b48ecbf7a26948f","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:18.473Z"},{"_id":"5c7d50b62b48ecbf7a269455","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:14.321Z"},{"_id":"5c7d50b42b48ecbf7a269442","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:22:12.468Z"},{"_id":"5c7d507d2b48ecbf7a26916c","message":"Light Küche was changed","__v":0,"created":"2019-03-04T16:21:17.006Z"}] + """.data(using: .utf8)! // swiftlint:enable line_length do { @@ -57,8 +56,8 @@ class OpenHABJSONParserTests: XCTestCase { // Contributed by Tobi-1234 in #348 func testJSONShortSitemapDecoder() { let json = """ -[{"name":"Haus","label":"Hauptmenü","link":"http://192.xxxx:8080/rest/sitemaps/Haus","homepage":{"link":"http://192.xxx:8080/rest/sitemaps/Haus/Haus","leaf":false,"widgets":[]}},{"name":"_default","label":"Home","link":"http://192.Xxx:8080/rest/sitemaps/_default","homepage":{"link":"http://192.Xxxx:8080/rest/sitemaps/_default/_default","leaf":false,"widgets":[]}}] -""" + [{"name":"Haus","label":"Hauptmenü","link":"http://192.xxxx:8080/rest/sitemaps/Haus","homepage":{"link":"http://192.xxx:8080/rest/sitemaps/Haus/Haus","leaf":false,"widgets":[]}},{"name":"_default","label":"Home","link":"http://192.Xxx:8080/rest/sitemaps/_default","homepage":{"link":"http://192.Xxxx:8080/rest/sitemaps/_default/_default","leaf":false,"widgets":[]}}] + """ let data = Data(json.utf8) do { let codingData = try decoder.decode([OpenHABSitemap.CodingData].self, from: data) @@ -70,27 +69,27 @@ class OpenHABJSONParserTests: XCTestCase { func testJSONItem() { let json = """ - { - "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch5_1", - "state": "OFF", - "stateDescription": { - "pattern": "Kellertest", - "readOnly": false, - "options": [] - }, - "editable": false, - "type": "Switch", - "name": "lcnLightSwitch5_1", - "label": "Licht Treppe Keller-EG", - "tags": [ - "Lighting" - ], - "groupNames": [ - "G_PresenceSimulation", - "gLcn" - ] - } -""".data(using: .utf8)! + { + "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch5_1", + "state": "OFF", + "stateDescription": { + "pattern": "Kellertest", + "readOnly": false, + "options": [] + }, + "editable": false, + "type": "Switch", + "name": "lcnLightSwitch5_1", + "label": "Licht Treppe Keller-EG", + "tags": [ + "Lighting" + ], + "groupNames": [ + "G_PresenceSimulation", + "gLcn" + ] + } + """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABItem.CodingData.self, from: json) @@ -102,8 +101,8 @@ class OpenHABJSONParserTests: XCTestCase { func testWidgetMapping() { let json = """ -[{"command": "0","label": "Overwrite"}, {"command": "1","label": "Calendar"}] -""" + [{"command": "0","label": "Overwrite"}, {"command": "1","label": "Calendar"}] + """ let data = Data(json.utf8) do { let decoded = try decoder.decode([OpenHABWidgetMapping].self, from: data) @@ -115,35 +114,35 @@ class OpenHABJSONParserTests: XCTestCase { func testJSONWidget() { let json = """ - { - "widgetId": "0000", - "type": "Switch", - "label": "Licht Treppe Keller-EG [Kellertest]", - "icon": "switch", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch5_1", - "state": "OFF", - "stateDescription": { - "pattern": "Kellertest", - "readOnly": false, - "options": [] - }, - "editable": false, - "type": "Switch", - "name": "lcnLightSwitch5_1", - "label": "Licht Treppe Keller-EG", - "tags": [ - "Lighting" - ], - "groupNames": [ - "G_PresenceSimulation", - "gLcn" - ] - }, - "widgets": [] - } -""".data(using: .utf8)! + { + "widgetId": "0000", + "type": "Switch", + "label": "Licht Treppe Keller-EG [Kellertest]", + "icon": "switch", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch5_1", + "state": "OFF", + "stateDescription": { + "pattern": "Kellertest", + "readOnly": false, + "options": [] + }, + "editable": false, + "type": "Switch", + "name": "lcnLightSwitch5_1", + "label": "Licht Treppe Keller-EG", + "tags": [ + "Lighting" + ], + "groupNames": [ + "G_PresenceSimulation", + "gLcn" + ] + }, + "widgets": [] + } + """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABWidget.CodingData.self, from: json) @@ -155,8 +154,8 @@ class OpenHABJSONParserTests: XCTestCase { func testLinkedPage() { let json = """ -{"id": "1302", "title": "EG Süd", "icon": "rollershutter", "link": "https://192.168.2.63:8444/rest/sitemaps/myHome/1302"} -""" + {"id": "1302", "title": "EG Süd", "icon": "rollershutter", "link": "https://192.168.2.63:8444/rest/sitemaps/myHome/1302"} + """ let data = Data(json.utf8) do { let decoded = try decoder.decode(OpenHABLinkedPage.self, from: data) @@ -168,8 +167,8 @@ class OpenHABJSONParserTests: XCTestCase { func testItem() { let json = """ -{"link": "https://192.168.2.63:8444/rest/items/lcnDFFOst", "state": "100.0", "editable": false, "type": "Rollershutter", "name": "lcnDFFOst", "label": "DFF Arbeitszimmer", "tags": [], "groupNames": [ "gDZ", "gDFF", "gLcn"]} -""" + {"link": "https://192.168.2.63:8444/rest/items/lcnDFFOst", "state": "100.0", "editable": false, "type": "Rollershutter", "name": "lcnDFFOst", "label": "DFF Arbeitszimmer", "tags": [], "groupNames": [ "gDZ", "gDFF", "gLcn"]} + """ let data = Data(json.utf8) do { let decoded = try decoder.decode(OpenHABItem.CodingData.self, from: data) @@ -181,91 +180,91 @@ class OpenHABJSONParserTests: XCTestCase { func testJSONLinkedPage() { let json = """ - { "id": "1304", - "title": "EG West", - "icon": "rollershutter", - "link": "https://192.168.2.63:8444/rest/sitemaps/myHome/1304", - "leaf": true, - "timeout": false, - "widgets": [ - { - "widgetId": "130400", - "type": "Switch", - "label": "Jalousie WZ West links", - "icon": "rollershutter", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestLinks", - "state": "0.0", - "editable": false, - "type": "Rollershutter", - "name": "lcnJalousieWZWestLinks", - "label": "Jalousie WZ West links", - "tags": [], - "groupNames": [ - "gWZ", - "gEGJalousien", - "gHausJalousie", - "gJalousienWest", - "gEGJalousienWest", - "gLcn" - ] - }, - "widgets": [] - }, - { - "widgetId": "130401", - "type": "Switch", - "label": "Jalousie WZ West Mitte", - "icon": "rollershutter", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestMitte", - "state": "0.0", - "editable": false, - "type": "Rollershutter", - "name": "lcnJalousieWZWestMitte", - "label": "Jalousie WZ West Mitte", - "tags": [], - "groupNames": [ - "gWZ", - "gEGJalousien", - "gHausJalousie", - "gJalousienWest", - "gEGJalousienWest", - "gLcn" - ] - }, - "widgets": [] - }, - { - "widgetId": "130402", - "type": "Switch", - "label": "Jalousie WZ West rechts", - "icon": "rollershutter", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestRechts", - "state": "0.0", - "editable": false, - "type": "Rollershutter", - "name": "lcnJalousieWZWestRechts", - "label": "Jalousie WZ West rechts", - "tags": [], - "groupNames": [ - "gWZ", - "gEGJalousien", - "gHausJalousie", - "gJalousienWest", - "gEGJalousienWest", - "gLcn" - ] - }, - "widgets": [] - } - ] -} -""".data(using: .utf8)! + { "id": "1304", + "title": "EG West", + "icon": "rollershutter", + "link": "https://192.168.2.63:8444/rest/sitemaps/myHome/1304", + "leaf": true, + "timeout": false, + "widgets": [ + { + "widgetId": "130400", + "type": "Switch", + "label": "Jalousie WZ West links", + "icon": "rollershutter", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestLinks", + "state": "0.0", + "editable": false, + "type": "Rollershutter", + "name": "lcnJalousieWZWestLinks", + "label": "Jalousie WZ West links", + "tags": [], + "groupNames": [ + "gWZ", + "gEGJalousien", + "gHausJalousie", + "gJalousienWest", + "gEGJalousienWest", + "gLcn" + ] + }, + "widgets": [] + }, + { + "widgetId": "130401", + "type": "Switch", + "label": "Jalousie WZ West Mitte", + "icon": "rollershutter", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestMitte", + "state": "0.0", + "editable": false, + "type": "Rollershutter", + "name": "lcnJalousieWZWestMitte", + "label": "Jalousie WZ West Mitte", + "tags": [], + "groupNames": [ + "gWZ", + "gEGJalousien", + "gHausJalousie", + "gJalousienWest", + "gEGJalousienWest", + "gLcn" + ] + }, + "widgets": [] + }, + { + "widgetId": "130402", + "type": "Switch", + "label": "Jalousie WZ West rechts", + "icon": "rollershutter", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnJalousieWZWestRechts", + "state": "0.0", + "editable": false, + "type": "Rollershutter", + "name": "lcnJalousieWZWestRechts", + "label": "Jalousie WZ West rechts", + "tags": [], + "groupNames": [ + "gWZ", + "gEGJalousien", + "gHausJalousie", + "gJalousienWest", + "gEGJalousienWest", + "gLcn" + ] + }, + "widgets": [] + } + ] + } + """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABLinkedPage.self, from: json) XCTAssertEqual(codingData.pageId, "1304", "OpenHABLinkedPage properly parsed") @@ -276,21 +275,21 @@ class OpenHABJSONParserTests: XCTestCase { func testJSONWidgetMapping() { let json = """ -[ - { - "command": "0", - "label": "Overwrite" - }, - { - "command": "1", - "label": "Kalender" - }, - { - "command": "2", - "label": "Automatik" - } -] -""".data(using: .utf8)! + [ + { + "command": "0", + "label": "Overwrite" + }, + { + "command": "1", + "label": "Kalender" + }, + { + "command": "2", + "label": "Automatik" + } + ] + """.data(using: .utf8)! do { let codingData = try decoder.decode([OpenHABWidgetMapping].self, from: json) XCTAssertEqual(codingData[0].label, "Overwrite", "WidgetMapping properly parsed") @@ -301,62 +300,62 @@ class OpenHABJSONParserTests: XCTestCase { func testJSONWidget2() { let json = """ -{ - "widgetId": "01", - "type": "Frame", - "label": "Eingang", - "icon": "frame", - "mappings": [], - "widgets": [ - { - "widgetId": "0100", - "type": "Switch", - "label": "Licht Eingang", - "icon": "switch", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch17_1", - "state": "ON", - "editable": false, - "type": "Switch", - "name": "lcnLightSwitch17_1", - "label": "Licht Eingang", - "tags": [ - "Lighting" - ], - "groupNames": [ - "G_PresenceSimulation", - "gLcn" - ] - }, - "widgets": [] - }, - { - "widgetId": "0101", - "type": "Switch", - "label": "Licht Eingang aussen", - "icon": "switch", - "mappings": [], - "item": { - "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch17_2", - "state": "OFF", - "editable": false, - "type": "Switch", - "name": "lcnLightSwitch17_2", - "label": "Licht Eingang aussen", - "tags": [ - "Lighting" - ], - "groupNames": [ - "G_PresenceSimulation", - "gLcn" - ] - }, - "widgets": [] - } - ] - } -""".data(using: .utf8)! + { + "widgetId": "01", + "type": "Frame", + "label": "Eingang", + "icon": "frame", + "mappings": [], + "widgets": [ + { + "widgetId": "0100", + "type": "Switch", + "label": "Licht Eingang", + "icon": "switch", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch17_1", + "state": "ON", + "editable": false, + "type": "Switch", + "name": "lcnLightSwitch17_1", + "label": "Licht Eingang", + "tags": [ + "Lighting" + ], + "groupNames": [ + "G_PresenceSimulation", + "gLcn" + ] + }, + "widgets": [] + }, + { + "widgetId": "0101", + "type": "Switch", + "label": "Licht Eingang aussen", + "icon": "switch", + "mappings": [], + "item": { + "link": "https://192.168.2.63:8444/rest/items/lcnLightSwitch17_2", + "state": "OFF", + "editable": false, + "type": "Switch", + "name": "lcnLightSwitch17_2", + "label": "Licht Eingang aussen", + "tags": [ + "Lighting" + ], + "groupNames": [ + "G_PresenceSimulation", + "gLcn" + ] + }, + "widgets": [] + } + ] + } + """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABWidget.CodingData.self, from: json) XCTAssertEqual(codingData.widgetId, "01", "Widget properly parsed") @@ -385,12 +384,13 @@ class OpenHABJSONParserTests: XCTestCase { XCTFail("Whoops, an error occured: \(error)") } } + // swiftlint:disable line_length func testWatchSitemap() { let json = """ -{"name":"watch","label":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch","homepage":{"id":"watch","title":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch/watch","leaf":false,"timeout":false,"widgets":[{"widgetId":"00","type":"Frame","label":"Ground floor","icon":"frame","mappings":[],"widgets":[{"widgetId":"0000","type":"Switch","label":"Licht Oberlicht","icon":"switch","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch14_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch14_1","label":"Licht Oberlicht","tags":["Lighting"],"groupNames":["G_PresenceSimulation","gLcn"]},"widgets":[]},{"widgetId":"0001","type":"Switch","label":"Licht Keller WC Decke","icon":"colorpicker","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch6_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch6_1","label":"Licht Keller WC Decke","category":"colorpicker","tags":["Lighting"],"groupNames":["gKellerLicht","gLcn"]},"widgets":[]}]}]}} -""".data(using: .utf8)! + {"name":"watch","label":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch","homepage":{"id":"watch","title":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch/watch","leaf":false,"timeout":false,"widgets":[{"widgetId":"00","type":"Frame","label":"Ground floor","icon":"frame","mappings":[],"widgets":[{"widgetId":"0000","type":"Switch","label":"Licht Oberlicht","icon":"switch","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch14_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch14_1","label":"Licht Oberlicht","tags":["Lighting"],"groupNames":["G_PresenceSimulation","gLcn"]},"widgets":[]},{"widgetId":"0001","type":"Switch","label":"Licht Keller WC Decke","icon":"colorpicker","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch6_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch6_1","label":"Licht Keller WC Decke","category":"colorpicker","tags":["Lighting"],"groupNames":["gKellerLicht","gLcn"]},"widgets":[]}]}]}} + """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: json) XCTAssertEqual(codingData.page.link, "https://192.168.2.15:8444/rest/sitemaps/watch/watch", "OpenHABSitemapPage properly parsed") @@ -400,44 +400,45 @@ class OpenHABJSONParserTests: XCTestCase { XCTFail("Whoops, an error occured: \(error)") } } + // swiftlint:enable line_length func testParsingforRollerShutter() { let jsonInputForGroup = """ -{ - "id": "watch", - "title": "Watch", - "link": "https://server/rest/sitemaps/watch/watch", - "leaf": true, - "timeout": false, - "widgets": [ - { - "widgetId": "00", - "type": "Switch", - "label": "Rollladen Erdgeschoss", - "icon": "blinds", - "mappings": [], - "item": { - "members": [], - "groupType": "Rollershutter", - "function": { - "name": "EQUALITY" - }, - "link": "https://server/rest/items/gRollladen_EG", - "state": "UNDEF", - "editable": false, - "type": "Group", - "name": "gRollladen_EG", - "label": "Rollladen Erdgeschoss", - "category": "blinds", - "tags": [], - "groupNames": [] - }, - "widgets": [] - } - ] -} -""" + { + "id": "watch", + "title": "Watch", + "link": "https://server/rest/sitemaps/watch/watch", + "leaf": true, + "timeout": false, + "widgets": [ + { + "widgetId": "00", + "type": "Switch", + "label": "Rollladen Erdgeschoss", + "icon": "blinds", + "mappings": [], + "item": { + "members": [], + "groupType": "Rollershutter", + "function": { + "name": "EQUALITY" + }, + "link": "https://server/rest/items/gRollladen_EG", + "state": "UNDEF", + "editable": false, + "type": "Group", + "name": "gRollladen_EG", + "label": "Rollladen Erdgeschoss", + "category": "blinds", + "tags": [], + "groupNames": [] + }, + "widgets": [] + } + ] + } + """ let data = Data(jsonInputForGroup.utf8) do { let codingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: data) @@ -451,49 +452,39 @@ class OpenHABJSONParserTests: XCTestCase { } func testJSONLargeSitemapParseSwift() { - let log = OSLog( - subsystem: "org.openhab.app", - category: "RecordDecoding" - ) + let log = OSLog(subsystem: "org.openhab.app", + category: "RecordDecoding") let signpostID = OSSignpostID(log: log) do { let jsonFile = "LargeSitemap" - os_signpost( - .begin, - log: log, - name: "Read File", - signpostID: signpostID, - "%{public}s", - jsonFile - ) + os_signpost(.begin, + log: log, + name: "Read File", + signpostID: signpostID, + "%{public}s", + jsonFile) let testBundle = Bundle(for: type(of: self)) let url = testBundle.url(forResource: jsonFile, withExtension: "json") let contents = try Data(contentsOf: url!) - os_signpost( - .end, - log: log, - name: "Read File", - signpostID: signpostID, - "%{public}s", - jsonFile - ) + os_signpost(.end, + log: log, + name: "Read File", + signpostID: signpostID, + "%{public}s", + jsonFile) - os_signpost( - .begin, - log: log, - name: "Decode JSON", - signpostID: signpostID, - "Begin" - ) + os_signpost(.begin, + log: log, + name: "Decode JSON", + signpostID: signpostID, + "Begin") let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: contents) - os_signpost( - .end, - log: log, - name: "Decode JSON", - signpostID: signpostID, - "End" - ) + os_signpost(.end, + log: log, + name: "Decode JSON", + signpostID: signpostID, + "End") let widget = codingData.page.widgets?[0] XCTAssertEqual(widget?.label, "Flat Scenes") diff --git a/openHABTestsSwift/OpenHABUserDefaultsTests.swift b/openHABTestsSwift/OpenHABUserDefaultsTests.swift index fa470666b..46a37d66b 100644 --- a/openHABTestsSwift/OpenHABUserDefaultsTests.swift +++ b/openHABTestsSwift/OpenHABUserDefaultsTests.swift @@ -9,7 +9,6 @@ import XCTest class OpenHABUserDefaultsTests: XCTestCase { - override func setUp() { super.setUp() let defaultsName = Bundle.main.bundleIdentifier! @@ -28,14 +27,13 @@ class OpenHABUserDefaultsTests: XCTestCase { // Testing the consistency between properties of Preferences and the corresponding entry in UserDefaults func testConsistency() { - XCTAssertEqual(Preferences.username, UserDefaults.standard.string(forKey: "username")) XCTAssertNotEqual(Preferences.username, UserDefaults.standard.string(forKey: "usern")) XCTAssertEqual(Preferences.localUrl, UserDefaults.standard.string(forKey: "localUrl")) XCTAssertEqual(Preferences.remoteUrl, UserDefaults.standard.string(forKey: "remoteUrl")) XCTAssertEqual(Preferences.password, UserDefaults.standard.string(forKey: "password")) XCTAssertEqual(Preferences.ignoreSSL, UserDefaults.standard.bool(forKey: "ignoreSSL")) - // XCTAssertEqual(Preferences.sitemapName, UserDefaults.standard.string(forKey: "sitemapName")) + // XCTAssertEqual(Preferences.sitemapName, UserDefaults.standard.string(forKey: "sitemapName")) XCTAssertEqual(Preferences.demomode, UserDefaults.standard.bool(forKey: "demomode")) XCTAssertEqual(Preferences.idleOff, UserDefaults.standard.bool(forKey: "idleOff")) XCTAssertEqual(Preferences.iconType, UserDefaults.standard.integer(forKey: "iconType")) diff --git a/openHABTestsSwift/OpenHABWatchTests.swift b/openHABTestsSwift/OpenHABWatchTests.swift index a7b06924c..d5419e4bc 100644 --- a/openHABTestsSwift/OpenHABWatchTests.swift +++ b/openHABTestsSwift/OpenHABWatchTests.swift @@ -9,190 +9,189 @@ import XCTest class OpenHABWatchTests: XCTestCase { - let jsonInput = """ -{ - "name": "watch", - "label": "Watch", - "link": "https://192.168.0.1:8080/rest/sitemaps/watch", - "homepage": { - "id": "watch", - "title": "Watch", - "link": "https://192.168.0.1:8080/rest/sitemaps/watch/watch", - "leaf": false, - "timeout": false, - "widgets": [ - { - "widgetId": "00", - "type": "Switch", - "label": "Haustür", - "icon": "lock", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/KeyMatic_Open", - "state": "OFF", - "stateDescription": { - "readOnly": false, - "options": [ + { + "name": "watch", + "label": "Watch", + "link": "https://192.168.0.1:8080/rest/sitemaps/watch", + "homepage": { + "id": "watch", + "title": "Watch", + "link": "https://192.168.0.1:8080/rest/sitemaps/watch/watch", + "leaf": false, + "timeout": false, + "widgets": [ + { + "widgetId": "00", + "type": "Switch", + "label": "Haustür", + "icon": "lock", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/KeyMatic_Open", + "state": "OFF", + "stateDescription": { + "readOnly": false, + "options": [ + ] + }, + "editable": false, + "type": "Switch", + "name": "KeyMatic_Open", + "label": "Haustuer", + "category": "lock", + "tags": [ + ], + "groupNames": [ + ] + }, + "widgets": [ ] }, - "editable": false, - "type": "Switch", - "name": "KeyMatic_Open", - "label": "Haustuer", - "category": "lock", - "tags": [ - ], - "groupNames": [ - ] - }, - "widgets": [ - ] - }, - { - "widgetId": "01", - "type": "Switch", - "label": "Garagentor", - "icon": "garage", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/Garagentor_Taster", - "state": "OFF", - "stateDescription": { - "readOnly": false, - "options": [ + { + "widgetId": "01", + "type": "Switch", + "label": "Garagentor", + "icon": "garage", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/Garagentor_Taster", + "state": "OFF", + "stateDescription": { + "readOnly": false, + "options": [ + ] + }, + "editable": false, + "type": "Switch", + "name": "Garagentor_Taster", + "label": "Garagentor", + "category": "garage", + "tags": [ + ], + "groupNames": [ + ] + }, + "widgets": [ ] }, - "editable": false, - "type": "Switch", - "name": "Garagentor_Taster", - "label": "Garagentor", - "category": "garage", - "tags": [ - ], - "groupNames": [ - ] - }, - "widgets": [ - ] - }, - { - "widgetId": "02", - "type": "Switch", - "label": "Garagentür [verriegelt]", - "icon": "lock", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/KeyMatic_Garage_State", - "state": "OFF", - "transformedState": "verriegelt", - "stateDescription": { - "pattern": "", - "readOnly": false, - "options": [ + { + "widgetId": "02", + "type": "Switch", + "label": "Garagentür [verriegelt]", + "icon": "lock", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/KeyMatic_Garage_State", + "state": "OFF", + "transformedState": "verriegelt", + "stateDescription": { + "pattern": "", + "readOnly": false, + "options": [ + ] + }, + "editable": false, + "type": "Switch", + "name": "KeyMatic_Garage_State", + "label": "Garagentuer entriegelt", + "category": "lock", + "tags": [ + ], + "groupNames": [ + ] + }, + "widgets": [ ] }, - "editable": false, - "type": "Switch", - "name": "KeyMatic_Garage_State", - "label": "Garagentuer entriegelt", - "category": "lock", - "tags": [ - ], - "groupNames": [ - ] - }, - "widgets": [ - ] - }, - { - "widgetId": "03", - "type": "Switch", - "label": "Küchenlicht", - "icon": "switch", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/Licht_EG_Kueche", - "state": "OFF", - "stateDescription": { - "readOnly": false, - "options": [ + { + "widgetId": "03", + "type": "Switch", + "label": "Küchenlicht", + "icon": "switch", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/Licht_EG_Kueche", + "state": "OFF", + "stateDescription": { + "readOnly": false, + "options": [ + ] + }, + "editable": false, + "type": "Switch", + "name": "Licht_EG_Kueche", + "label": "Kuechenlampe", + "tags": [ + ], + "groupNames": [ + "gEG", + "Lichter", + "Simulation" + ] + }, + "widgets": [ ] }, - "editable": false, - "type": "Switch", - "name": "Licht_EG_Kueche", - "label": "Kuechenlampe", - "tags": [ - ], - "groupNames": [ - "gEG", - "Lichter", - "Simulation" - ] - }, - "widgets": [ - ] - }, - { - "widgetId": "04", - "type": "Switch", - "label": "Bewässerung", - "icon": "switch", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/HK_Bewaesserung", - "state": "OFF", - "editable": false, - "type": "Switch", - "name": "HK_Bewaesserung", - "label": "Bewaesserung", - "tags": [ - "Lighting" - ], - "groupNames": [ - ] - }, - "widgets": [ - ] - }, - { - "widgetId": "05", - "type": "Switch", - "label": "Pumpe", - "icon": "switch", - "mappings": [ - ], - "item": { - "link": "https://192.168.0.1:8080/rest/items/Pumpe_Garten", - "state": "OFF", - "stateDescription": { - "readOnly": false, - "options": [ + { + "widgetId": "04", + "type": "Switch", + "label": "Bewässerung", + "icon": "switch", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/HK_Bewaesserung", + "state": "OFF", + "editable": false, + "type": "Switch", + "name": "HK_Bewaesserung", + "label": "Bewaesserung", + "tags": [ + "Lighting" + ], + "groupNames": [ + ] + }, + "widgets": [ ] }, - "editable": false, - "type": "Switch", - "name": "Pumpe_Garten", - "label": "Pumpe", - "tags": [ - ], - "groupNames": [ - "Garten" - ] - }, - "widgets": [ + { + "widgetId": "05", + "type": "Switch", + "label": "Pumpe", + "icon": "switch", + "mappings": [ + ], + "item": { + "link": "https://192.168.0.1:8080/rest/items/Pumpe_Garten", + "state": "OFF", + "stateDescription": { + "readOnly": false, + "options": [ + ] + }, + "editable": false, + "type": "Switch", + "name": "Pumpe_Garten", + "label": "Pumpe", + "tags": [ + ], + "groupNames": [ + "Garten" + ] + }, + "widgets": [ + ] + } ] } - ] - } -} -""" + } + """ let decoder = JSONDecoder() @@ -206,9 +205,9 @@ class OpenHABWatchTests: XCTestCase { override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. } -// Pre-Decodable JSON parsing - func testSiteMapForWatchParsing() { + // Pre-Decodable JSON parsing + func testSiteMapForWatchParsing() { let data = Data(jsonInput.utf8) do { // swiftlint:disable empty_count @@ -234,9 +233,9 @@ class OpenHABWatchTests: XCTestCase { XCTFail("Failed parsing") } } -// Parsing to [Item] - func testSiteMapForWatchParsingWithDecodable() { + // Parsing to [Item] + func testSiteMapForWatchParsingWithDecodable() { var items: [Item] = [] let data = Data(jsonInput.utf8) @@ -245,39 +244,36 @@ class OpenHABWatchTests: XCTestCase { XCTAssert(codingData.label == "Watch", "OpenHABSitemap properly parsed") XCTAssert(codingData.page.widgets?[0].type == "Switch", "widget properly parsed") let widgets = try require(codingData.page.widgets) - items = widgets.compactMap { Item.init(with: $0.item) } - XCTAssert(items[0].name == "KeyMatic_Open", "Construction of items failed" ) + items = widgets.compactMap { Item(with: $0.item) } + XCTAssert(items[0].name == "KeyMatic_Open", "Construction of items failed") } catch { XCTFail("Whoops, an error occured: \(error)") } - } -// Decodable parsing to Frame + // Decodable parsing to Frame func testSiteMapForWatchParsingWithDecodabletoFrame() { - var frame: Frame let data = Data(jsonInput.utf8) do { let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: data) - frame = Frame.init(with: codingData)! - XCTAssert(frame.items[0].name == "KeyMatic_Open", "Parsing of Frame failed" ) + frame = Frame(with: codingData)! + XCTAssert(frame.items[0].name == "KeyMatic_Open", "Parsing of Frame failed") } catch { XCTFail("Whoops, an error occured: \(error)") } } -// Decodable parsing to Sitemap -func testSiteMapForWatchParsingWithDecodabletoSitemap() { - - let data = Data(jsonInput.utf8) - do { - let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: data) - let sitemap = try require(Sitemap.init(with: codingData)) - XCTAssert(sitemap.frames[0].items[0].name == "KeyMatic_Open", "Parsing of Frame failed" ) - } catch { - XCTFail("Whoops, an error occured: \(error)") + // Decodable parsing to Sitemap + func testSiteMapForWatchParsingWithDecodabletoSitemap() { + let data = Data(jsonInput.utf8) + do { + let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: data) + let sitemap = try require(Sitemap(with: codingData)) + XCTAssert(sitemap.frames[0].items[0].name == "KeyMatic_Open", "Parsing of Frame failed") + } catch { + XCTFail("Whoops, an error occured: \(error)") + } } } -} diff --git a/openHABTestsSwift/OpenHABXMLParserTests.swift b/openHABTestsSwift/OpenHABXMLParserTests.swift index 60acc1087..e7ed6cb0a 100644 --- a/openHABTestsSwift/OpenHABXMLParserTests.swift +++ b/openHABTestsSwift/OpenHABXMLParserTests.swift @@ -13,7 +13,6 @@ enum TestingError: Error { } class OpenHABXMLParserTests: XCTestCase { - override func setUp() { // Put setup code here. This method is called before the invocation of each test method in the class. } @@ -27,13 +26,13 @@ class OpenHABXMLParserTests: XCTestCase { // Use XCTAssert and related functions to verify your tests produce the correct results. let xml = """ - - NumberItem - Office_Temperature - 21.20 - http://192.168.0.249:8080/rest/items/Office_Temperature - -""".data(using: .utf8)! + + NumberItem + Office_Temperature + 21.20 + http://192.168.0.249:8080/rest/items/Office_Temperature + + """.data(using: .utf8)! do { let document = try XMLDocument(data: xml) diff --git a/openHABTestsSwift/RESTAPITest.swift b/openHABTestsSwift/RESTAPITest.swift index b18d3e142..aa2884b65 100644 --- a/openHABTestsSwift/RESTAPITest.swift +++ b/openHABTestsSwift/RESTAPITest.swift @@ -10,7 +10,6 @@ import XCTest class RESTAPITest: XCTestCase { - override func setUp() { super.setUp() @@ -51,8 +50,8 @@ class RESTAPITest: XCTestCase { let pageToLoadUrl = URL(string: "http://192.168.2.16")! let pageRequest = URLRequest(url: pageToLoadUrl) let registrationOperation = NetworkConnection.shared.manager.request(pageRequest) - .validate(statusCode: 200..<300) - .responseData { (response) in + .validate(statusCode: 200 ..< 300) + .responseData { response in XCTAssertEqual(response.response?.statusCode, 200) expectation.fulfill() } @@ -63,30 +62,28 @@ class RESTAPITest: XCTestCase { } func testRegisterApp() { - // given MockURLProtocol.responseWithStatusCode(code: 200) let expectation = XCTestExpectation(description: "Register App") // when - NetworkConnection.register(prefsURL: "http://192.168.2.16", deviceToken: "", deviceId: "", deviceName: "") { (response) in - XCTAssertEqual(response.response?.statusCode, 200) - expectation.fulfill() + NetworkConnection.register(prefsURL: "http://192.168.2.16", deviceToken: "", deviceId: "", deviceName: "") { response in + XCTAssertEqual(response.response?.statusCode, 200) + expectation.fulfill() } // then wait(for: [expectation], timeout: 3) } func testSitemap() { - // given MockURLProtocol.responseWithStatusCode(code: 200) let expectation = XCTestExpectation(description: "Register App") // when - NetworkConnection.sitemaps(openHABRootUrl: "") { (response) in + NetworkConnection.sitemaps(openHABRootUrl: "") { response in XCTAssertEqual(response.response?.statusCode, 200) expectation.fulfill() } @@ -95,14 +92,13 @@ class RESTAPITest: XCTestCase { } func testTracker() { - // given MockURLProtocol.responseWithStatusCode(code: 200) let expectation = XCTestExpectation(description: "Register App") // when - NetworkConnection.tracker(openHABRootUrl: "") { (response) in + NetworkConnection.tracker(openHABRootUrl: "") { response in XCTAssertEqual(response.response?.statusCode, 200) expectation.fulfill() } diff --git a/openHABUITests/OpenHABUITests.swift b/openHABUITests/OpenHABUITests.swift index c88d52c87..71a45f8fb 100644 --- a/openHABUITests/OpenHABUITests.swift +++ b/openHABUITests/OpenHABUITests.swift @@ -9,7 +9,6 @@ import XCTest class OpenHABUITests: XCTestCase { - override func setUp() { let app = XCUIApplication() app.launchEnvironment = ["UITest": "1"] @@ -79,6 +78,5 @@ class OpenHABUITests: XCTestCase { hamburgerButton.tap() sleep(1) snapshot("7_Settings") - } } diff --git a/openHABWatch Extension/ButtonTableRowController.swift b/openHABWatch Extension/ButtonTableRowController.swift index 7381a82c9..f496eb438 100644 --- a/openHABWatch Extension/ButtonTableRowController.swift +++ b/openHABWatch Extension/ButtonTableRowController.swift @@ -10,11 +10,10 @@ import Foundation import WatchKit class ButtonTableRowController: NSObject { - var item: Item? var interfaceController: InterfaceController? - @IBOutlet var buttonSwitch: WKInterfaceSwitch! + @IBOutlet private var buttonSwitch: WKInterfaceSwitch! @IBAction func doSwitchButtonPressed(_ value: Bool) { guard let item = item else { return } @@ -40,19 +39,18 @@ class ButtonTableRowController: NSObject { } private func switchOpenHabItem(for item: Item, command: String) { - interfaceController!.displayActivityImage() - OpenHabService.singleton.switchOpenHabItem(for: item, command: command) {(data, response, error) -> Void in + OpenHabService.singleton.switchOpenHabItem(for: item, command: command) { (data, response, error) -> Void in self.interfaceController!.hideActivityImage() - guard let data = data, error == nil else { // check for fundamental networking error + guard let data = data, error == nil else { // check for fundamental networking error self.interfaceController!.displayAlert(message: "error=\(String(describing: error))") return } - if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors + if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors let message = "statusCode should be 200, but is \(httpStatus.statusCode)\n" + - "response = \(String(describing: response))" + "response = \(String(describing: response))" self.interfaceController!.displayAlert(message: message) } diff --git a/openHABWatch Extension/ComplicationController.swift b/openHABWatch Extension/ComplicationController.swift index c324412ed..32c0a850b 100644 --- a/openHABWatch Extension/ComplicationController.swift +++ b/openHABWatch Extension/ComplicationController.swift @@ -10,14 +10,12 @@ import ClockKit import Foundation class ComplicationController: NSObject, CLKComplicationDataSource { - // No Timetravel supported func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) { handler([]) } func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) { - let template = getTemplate(complication: complication) if template != nil { handler(CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template!)) @@ -27,12 +25,10 @@ class ComplicationController: NSObject, CLKComplicationDataSource { // MARK: - Placeholder Templates func getPlaceholderTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) { - handler(getTemplate(complication: complication)) } fileprivate func getTemplate(complication: CLKComplication) -> CLKComplicationTemplate? { - // default ist circularSmall var template: CLKComplicationTemplate? diff --git a/openHABWatch Extension/ExtensionDelegate.swift b/openHABWatch Extension/ExtensionDelegate.swift index 508f96b9c..e27545ed4 100644 --- a/openHABWatch Extension/ExtensionDelegate.swift +++ b/openHABWatch Extension/ExtensionDelegate.swift @@ -10,7 +10,6 @@ import WatchConnectivity import WatchKit class ExtensionDelegate: NSObject, WKExtensionDelegate { - var session: WCSession? { didSet { if let session = session { @@ -66,5 +65,4 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate { } } } - } diff --git a/openHABWatch Extension/InterfaceController.swift b/openHABWatch Extension/InterfaceController.swift index e590571e9..010874b07 100644 --- a/openHABWatch Extension/InterfaceController.swift +++ b/openHABWatch Extension/InterfaceController.swift @@ -10,9 +10,8 @@ import Foundation import WatchKit class InterfaceController: WKInterfaceController { - - @IBOutlet weak var activityImage: WKInterfaceImage! - @IBOutlet weak var buttonTable: WKInterfaceTable! + @IBOutlet private var activityImage: WKInterfaceImage! + @IBOutlet private var buttonTable: WKInterfaceTable! override func awake(withContext context: Any?) { super.awake(withContext: context) @@ -25,7 +24,7 @@ class InterfaceController: WKInterfaceController { // This method is called when watch view controller is about to be visible to user super.willActivate() - self.refresh(Preferences.sitemap) + refresh(Preferences.sitemap) // load the current Sitemap OpenHabService.singleton.readSitemap { (sitemap, errorString) -> Void in @@ -42,15 +41,14 @@ class InterfaceController: WKInterfaceController { } } - fileprivate func refresh(_ sitemap: (Sitemap)) { - + fileprivate func refresh(_ sitemap: Sitemap) { if sitemap.frames.isEmpty { return } - self.buttonTable.setNumberOfRows(sitemap.frames[0].items.count, withRowType: "buttonRow") - for i in 0.. Swift.Void) { let protectionSpace = challenge.protectionSpace if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let serverTrust = protectionSpace.serverTrust { - if Preferences.ignoreSSL { let credential = URLCredential(trust: serverTrust) os_log("Warning - ignoring invalid certificates", log: OSLog.remoteAccess, type: .info) @@ -43,8 +41,8 @@ class CertificatePinningURLSessionDelegate: NSObject, URLSessionDelegate { let certificateCount = SecTrustGetCertificateCount(serverTrust) guard certificateCount > 0, let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else { - completionHandler(.cancelAuthenticationChallenge, nil) - return + completionHandler(.cancelAuthenticationChallenge, nil) + return } let serverCertificateData = SecCertificateCopyData(certificate) as Data @@ -60,7 +58,7 @@ class CertificatePinningURLSessionDelegate: NSObject, URLSessionDelegate { completionHandler(.cancelAuthenticationChallenge, nil) } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { - self.evaluateClientTrust(challenge: challenge) + evaluateClientTrust(challenge: challenge) } else { if challenge.previousFailureCount == 0 { let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) @@ -76,7 +74,7 @@ class CertificatePinningURLSessionDelegate: NSObject, URLSessionDelegate { if let dns = dns { let identity = clientCertificateManager.evaluateTrust(distinguishedNames: dns) if let identity = identity { - let credential = URLCredential.init(identity: identity, certificates: nil, persistence: URLCredential.Persistence.forSession) + let credential = URLCredential(identity: identity, certificates: nil, persistence: URLCredential.Persistence.forSession) challenge.sender!.use(credential, for: challenge) return } @@ -93,7 +91,7 @@ extension Certificate { guard let file = bundle.url(forResource: $0, withExtension: "cer"), let data = try? Data(contentsOf: file), let cert = SecCertificateCreateWithData(nil, data as CFData) else { - return nil + return nil } return Certificate(certificate: cert, data: data) } @@ -111,6 +109,6 @@ extension Certificate { let isValid = (result == .unspecified || result == .proceed) // Validate host certificate against pinned certificate. - return isValid && certData == self.data + return isValid && certData == data } } diff --git a/openHABWatch Extension/app/AppState.swift b/openHABWatch Extension/app/AppState.swift index d9ad9aee1..fe5887645 100644 --- a/openHABWatch Extension/app/AppState.swift +++ b/openHABWatch Extension/app/AppState.swift @@ -9,7 +9,6 @@ import Foundation class AppState { - static let singleton = AppState() var active = false diff --git a/openHABWatch Extension/domain/Frame.swift b/openHABWatch Extension/domain/Frame.swift index ff25ad8af..9930b4fde 100644 --- a/openHABWatch Extension/domain/Frame.swift +++ b/openHABWatch Extension/domain/Frame.swift @@ -9,7 +9,6 @@ import Foundation class Frame: NSObject { - let items: [Item] init(items: [Item]) { @@ -20,6 +19,6 @@ class Frame: NSObject { extension Frame { convenience init? (with codingData: OpenHABSitemap.CodingData?) { guard let widgets = codingData?.page.widgets else { return nil } - self.init(items: widgets.compactMap { Item.init(with: $0.item) }) + self.init(items: widgets.compactMap { Item(with: $0.item) }) } } diff --git a/openHABWatch Extension/domain/Item.swift b/openHABWatch Extension/domain/Item.swift index a6682facf..2061e7b5d 100644 --- a/openHABWatch Extension/domain/Item.swift +++ b/openHABWatch Extension/domain/Item.swift @@ -9,7 +9,6 @@ import Foundation class Item: NSObject { - let name: String let label: String var state: String diff --git a/openHABWatch Extension/domain/Sitemap.swift b/openHABWatch Extension/domain/Sitemap.swift index 43df54f6e..cf7b73c5d 100644 --- a/openHABWatch Extension/domain/Sitemap.swift +++ b/openHABWatch Extension/domain/Sitemap.swift @@ -9,7 +9,6 @@ import Foundation class Sitemap: NSObject { - let frames: [Frame] init(frames: [Frame]) { @@ -19,7 +18,7 @@ class Sitemap: NSObject { extension Sitemap { convenience init? (with codingData: OpenHABSitemap.CodingData?) { - let frame = Frame.init(with: codingData)! + let frame = Frame(with: codingData)! self.init(frames: [frame]) } } diff --git a/openHABWatch Extension/external/AppMessageService.swift b/openHABWatch Extension/external/AppMessageService.swift index 12bbc9d3d..f49fb45a1 100644 --- a/openHABWatch Extension/external/AppMessageService.swift +++ b/openHABWatch Extension/external/AppMessageService.swift @@ -12,11 +12,9 @@ import WatchKit // This class handles values that are passed from the ios app. class AppMessageService: NSObject, WCSessionDelegate { - static let singleton = AppMessageService() func updateValuesFromApplicationContext(_ applicationContext: [String: AnyObject]) { - if let localUrl = applicationContext["localUrl"] as? String { Preferences.localUrl = localUrl } @@ -44,7 +42,6 @@ class AppMessageService: NSObject, WCSessionDelegate { @available(watchOSApplicationExtension 2.2, *) func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { - DispatchQueue.main.async { () -> Void in self.updateValuesFromApplicationContext(session.receivedApplicationContext as [String: AnyObject]) diff --git a/openHABWatch Extension/external/OpenHabService.swift b/openHABWatch Extension/external/OpenHabService.swift index 11742d3b3..3f992c6d8 100644 --- a/openHABWatch Extension/external/OpenHabService.swift +++ b/openHABWatch Extension/external/OpenHabService.swift @@ -10,12 +10,10 @@ import Foundation import os.log class OpenHabService { - static let singleton = OpenHabService() /* Reads the sitemap that should be displayed on the watch */ - func readSitemap(_ resultHandler : @escaping ((Sitemap, String) -> Void)) { - + func readSitemap(_ resultHandler: @escaping ((Sitemap, String) -> Void)) { let baseUrl = Preferences.readActiveUrl() let sitemapName = Preferences.sitemapName if baseUrl == "" { @@ -27,14 +25,13 @@ class OpenHabService { guard let requestUrl = Endpoint.watchSitemap(openHABRootUrl: baseUrl, sitemapName: sitemapName).url else { return } let request = URLRequest(url: requestUrl, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20) // let session = URLSession.shared - let session = URLSession( - configuration: URLSessionConfiguration.ephemeral, - delegate: CertificatePinningURLSessionDelegate(), - delegateQueue: nil) + let session = URLSession(configuration: URLSessionConfiguration.ephemeral, + delegate: CertificatePinningURLSessionDelegate(), + delegateQueue: nil) let task = session.dataTask(with: request) { (data, _, error) -> Void in guard error == nil else { - resultHandler(Sitemap.init(frames: []), "Can't read the sitemap from '\(requestUrl)'. Message is '\(String(describing: error))'") + resultHandler(Sitemap(frames: []), "Can't read the sitemap from '\(requestUrl)'. Message is '\(String(describing: error))'") return } guard let data = data else { return } @@ -44,10 +41,10 @@ class OpenHabService { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full) let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: data) - if let sitemap = Sitemap.init(with: codingData) { + if let sitemap = Sitemap(with: codingData) { resultHandler(sitemap, "") } - } catch let error { + } catch { os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) } } @@ -55,17 +52,16 @@ class OpenHabService { task.resume() } - func switchOpenHabItem(for item: Item, command: String, _ resultHandler : @escaping ((Data?, URLResponse?, Error?) -> Void)) { + func switchOpenHabItem(for item: Item, command: String, _ resultHandler: @escaping ((Data?, URLResponse?, Error?) -> Void)) { guard let commandUrl = URL(string: item.link) else { return } var request = URLRequest(url: commandUrl) request.setValue("text/plain", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" let postString = command request.httpBody = postString.data(using: .utf8) - let session = URLSession( - configuration: URLSessionConfiguration.ephemeral, - delegate: CertificatePinningURLSessionDelegate(), - delegateQueue: nil) + let session = URLSession(configuration: URLSessionConfiguration.ephemeral, + delegate: CertificatePinningURLSessionDelegate(), + delegateQueue: nil) let task = session.dataTask(with: request) { data, response, error in DispatchQueue.main.sync { resultHandler(data, response, error) diff --git a/openHABWatch Extension/repository/UserDefaultsRepository.swift b/openHABWatch Extension/repository/UserDefaultsRepository.swift index f6cf16b94..0e793b0b1 100644 --- a/openHABWatch Extension/repository/UserDefaultsRepository.swift +++ b/openHABWatch Extension/repository/UserDefaultsRepository.swift @@ -12,14 +12,12 @@ let defaultValues = ["username": "test", "password": "test", "sitemapName": "wat // Convenient access to UserDefaults // Much shorter but to be reworked when Property Wrappers are available struct Preferences { - static private let defaults = UserDefaults.standard static var localUrl: String { get { guard let localUrl = defaults.string(forKey: #function) else { return "" } - let trimmedUri = uriWithoutTrailingSlashes(localUrl).trimmingCharacters( - in: CharacterSet.whitespacesAndNewlines) + let trimmedUri = uriWithoutTrailingSlashes(localUrl).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) if !validateUrl(trimmedUri) { return "" } return trimmedUri } @@ -29,23 +27,24 @@ struct Preferences { static var remoteUrl: String { get { guard let localUrl = defaults.string(forKey: #function) else { return "https://openhab.org:8444" } - let trimmedUri = uriWithoutTrailingSlashes(localUrl).trimmingCharacters( - in: CharacterSet.whitespacesAndNewlines) + let trimmedUri = uriWithoutTrailingSlashes(localUrl).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) if !validateUrl(trimmedUri) { return "" } return trimmedUri - } + } set { defaults.setValue(newValue, forKey: #function) } } static var username: String { get { guard let string = defaults.string(forKey: #function) else { return defaultValues[#function]! } - return string } + return string + } set { defaults.setValue(newValue, forKey: #function) } } static var password: String { get { guard let string = defaults.string(forKey: #function) else { return defaultValues[#function]! } - return string } + return string + } set { defaults.setValue(newValue, forKey: #function) } } @@ -56,7 +55,8 @@ struct Preferences { static var sitemapName: String { get { guard let string = defaults.string(forKey: #function) else { return defaultValues[#function]! } - return string } + return string + } set { defaults.setValue(newValue, forKey: #function) } } @@ -77,12 +77,12 @@ struct Preferences { static var defaultSitemap: String { get { guard let string = defaults.string(forKey: #function) else { return defaultValues[#function]! } - return string } + return string + } set { defaults.setValue(newValue, forKey: #function) } } static func readActiveUrl() -> String { - if Preferences.remoteUrl != "" { return Preferences.remoteUrl } @@ -91,7 +91,7 @@ struct Preferences { fileprivate static func validateUrl(_ stringURL: String) -> Bool { // return nil if the URL has not a valid format - let url: URL? = URL.init(string: stringURL) + let url: URL? = URL(string: stringURL) return url != nil } @@ -102,5 +102,4 @@ struct Preferences { return String(hostUri[.. Date: Mon, 23 Sep 2019 17:46:22 +0200 Subject: [PATCH 06/76] add haptic feedback, refs #410 Signed-off-by: weak --- openHAB/RollershutterUITableViewCell.swift | 6 +++++- openHAB/SegmentedUITableViewCell.swift | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/openHAB/RollershutterUITableViewCell.swift b/openHAB/RollershutterUITableViewCell.swift index f42331709..f4560b7a6 100644 --- a/openHAB/RollershutterUITableViewCell.swift +++ b/openHAB/RollershutterUITableViewCell.swift @@ -12,10 +12,11 @@ import DynamicButton import os.log class RollershutterUITableViewCell: GenericUITableViewCell { + private let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + @IBOutlet private var downButton: DynamicButton! @IBOutlet private var stopButton: DynamicButton! @IBOutlet private var upButton: DynamicButton! - @IBOutlet private var customDetailText: UILabel! override func initialize() { @@ -53,18 +54,21 @@ class RollershutterUITableViewCell: GenericUITableViewCell { func upButtonPressed() { os_log("up button pressed", log: .viewCycle, type: .info) widget.sendCommand("UP") + feedbackGenerator.impactOccurred() } @objc func stopButtonPressed() { os_log("stop button pressed", log: .viewCycle, type: .info) widget.sendCommand("STOP") + feedbackGenerator.impactOccurred() } @objc func downButtonPressed() { os_log("down button pressed", log: .viewCycle, type: .info) widget.sendCommand("DOWN") + feedbackGenerator.impactOccurred() } } diff --git a/openHAB/SegmentedUITableViewCell.swift b/openHAB/SegmentedUITableViewCell.swift index acce1ac54..63993584d 100644 --- a/openHAB/SegmentedUITableViewCell.swift +++ b/openHAB/SegmentedUITableViewCell.swift @@ -11,8 +11,11 @@ import os.log import UIKit class SegmentedUITableViewCell: GenericUITableViewCell { + private let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + // @IBOutlet private var customTextLabel: UILabel! @IBOutlet private var widgetSegmentControl: UISegmentedControl! + required init?(coder: NSCoder) { super.init(coder: coder) @@ -49,5 +52,6 @@ class SegmentedUITableViewCell: GenericUITableViewCell { os_log("Segment pressed %d", log: .default, type: .info, Int(segmentedControl?.selectedSegmentIndex ?? 0)) let mapping = widget.mappings[segmentedControl?.selectedSegmentIndex ?? 0] widget.sendCommand(mapping.command) + feedbackGenerator.impactOccurred() } } From f438c36eafd0da36769ac4081c278172d763e515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Mon, 23 Sep 2019 21:05:53 +0200 Subject: [PATCH 07/76] Applied swiftlint rule private_action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- .swiftlint.yml | 1 + Podfile.lock | 2 +- openHAB/ColorPickerUITableViewCell.swift | 2 +- openHAB/SliderUITableViewCell.swift | 6 +++--- openHABWatch Extension/ButtonTableRowController.swift | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 84e57323e..4a1cd6a8f 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -15,6 +15,7 @@ opt_in_rules: - file_types_order - type_contents_order - private_outlet + - private_action disabled_rules: # rule identifiers to exclude from running - force_cast - todo diff --git a/Podfile.lock b/Podfile.lock index dc0ec3016..e1d756937 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -151,4 +151,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 7992aabfa3cc345bf07a1ead0bc7074376d15369 -COCOAPODS: 1.7.5 +COCOAPODS: 1.7.1 diff --git a/openHAB/ColorPickerUITableViewCell.swift b/openHAB/ColorPickerUITableViewCell.swift index 7011063e4..5ad088ced 100644 --- a/openHAB/ColorPickerUITableViewCell.swift +++ b/openHAB/ColorPickerUITableViewCell.swift @@ -38,7 +38,7 @@ class ColorPickerUITableViewCell: GenericUITableViewCell { separatorInset = .zero } - @IBAction func colorButtonPressed(_ sender: Any) { + @IBAction private func colorButtonPressed(_ sender: Any) { delegate?.didPressColorButton(self) } diff --git a/openHAB/SliderUITableViewCell.swift b/openHAB/SliderUITableViewCell.swift index e7acccf09..ebda6f870 100644 --- a/openHAB/SliderUITableViewCell.swift +++ b/openHAB/SliderUITableViewCell.swift @@ -31,16 +31,16 @@ class SliderUITableViewCell: GenericUITableViewCell { separatorInset = .zero } - @IBAction func sliderValueChanged(_ sender: Any) { + @IBAction private func sliderValueChanged(_ sender: Any) { let widgetValue = adj(Double(widgetSlider?.value ?? Float(widget.minValue))) customDetailText?.text = valueText(widgetValue) } - @IBAction func sliderTouchUp(_ sender: Any) { + @IBAction private func sliderTouchUp(_ sender: Any) { sliderDidEndSliding(widgetSlider) } - @IBAction func sliderTouchOutside(_ sender: Any) { + @IBAction private func sliderTouchOutside(_ sender: Any) { sliderDidEndSliding(widgetSlider) } diff --git a/openHABWatch Extension/ButtonTableRowController.swift b/openHABWatch Extension/ButtonTableRowController.swift index f496eb438..6181db700 100644 --- a/openHABWatch Extension/ButtonTableRowController.swift +++ b/openHABWatch Extension/ButtonTableRowController.swift @@ -15,7 +15,7 @@ class ButtonTableRowController: NSObject { @IBOutlet private var buttonSwitch: WKInterfaceSwitch! - @IBAction func doSwitchButtonPressed(_ value: Bool) { + @IBAction private func doSwitchButtonPressed(_ value: Bool) { guard let item = item else { return } let command = value ? "ON" : "OFF" switchOpenHabItem(for: item, command: command) From b270b0ffeca56db63ef048865470ef06f2b2237a Mon Sep 17 00:00:00 2001 From: Mimo Date: Mon, 23 Sep 2019 21:16:44 +0200 Subject: [PATCH 08/76] dark mode Support (#372) (#408) * dark mode Support (#372) adjustment to storyboard and hard-coded colors to support dark mode in iOS 13 Closes #372 Signed-off-by: Michel Mohrmann * dark mode Support (#372) SideMenu 6 Closes #372 Signed-off-by: Michel Mohrmann From c1c6165918ef766e55bc2732bd2fa8e0fbe8fe1e Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Mon, 23 Sep 2019 21:26:08 +0200 Subject: [PATCH 09/76] Migrate sidemenu (#418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix for #409 Signed-off-by: Tim Müller-Seydlitz * Improving test stability by setting UserDefaults for testing to default values Signed-off-by: Tim Müller-Seydlitz * Migration to SideMenu 6.x: Migration to new syntax Renamed DrawerTableType enum cases Signed-off-by: Tim Müller-Seydlitz * Setting the defaultSitemap to sitemap selected in side menu. - Dirty but working for the moment Signed-off-by: Tim Müller-Seydlitz * Setting up parameters for SideMenu Signed-off-by: Tim Müller-Seydlitz * dark mode Support (#372) adjustment to storyboard and hard-coded colors to support dark mode in iOS 13 Closes #372 Signed-off-by: Michel Mohrmann Signed-off-by: Tim Müller-Seydlitz * Version Bump to 65 * Fixes #416 Signed-off-by: Tim Müller-Seydlitz * Version Bump to 66 * Migrated gear/bell symbols to SF Symbol on iOS 13 Signed-off-by: Tim Müller-Seydlitz --- openHAB/Base.lproj/Main.storyboard | 16 +++++++-- openHAB/DrawerUITableViewCell.swift | 1 + .../OpenHABDrawerTableViewController.swift | 35 +++++++++++++------ openHAB/OpenHABViewController.swift | 1 - .../OpenHABUserDefaultsTests.swift | 16 +++++++++ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/openHAB/Base.lproj/Main.storyboard b/openHAB/Base.lproj/Main.storyboard index 1f60ae6b7..1c75b0511 100644 --- a/openHAB/Base.lproj/Main.storyboard +++ b/openHAB/Base.lproj/Main.storyboard @@ -58,6 +58,7 @@ @@ -137,6 +138,7 @@ @@ -282,6 +284,7 @@ @@ -320,6 +323,7 @@ @@ -366,6 +370,7 @@ @@ -443,6 +448,7 @@ @@ -1038,6 +1044,7 @@ @@ -1078,6 +1085,7 @@ + @@ -1123,6 +1131,7 @@ + @@ -1152,6 +1161,7 @@ + @@ -1181,6 +1191,7 @@ + @@ -1210,6 +1221,7 @@ + @@ -1384,7 +1396,7 @@ - + @@ -1413,7 +1425,7 @@ - + diff --git a/openHAB/DrawerUITableViewCell.swift b/openHAB/DrawerUITableViewCell.swift index d3c942a14..1d89c9f93 100644 --- a/openHAB/DrawerUITableViewCell.swift +++ b/openHAB/DrawerUITableViewCell.swift @@ -11,6 +11,7 @@ import os.log import UIKit class DrawerUITableViewCell: UITableViewCell { + // swiftlint:disable private_outlet @IBOutlet private(set) var customTextLabel: UILabel! @IBOutlet private(set) var customImageView: UIView! diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index 79a0bf58e..d4cf315a7 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -175,17 +175,30 @@ class OpenHABDrawerTableViewController: UITableViewController { cell.customTextLabel?.text = drawerItem.label - let buttonIcon = DynamicButton(frame: cell.customImageView.bounds) - buttonIcon.bounceButtonOnTouch = false - buttonIcon.strokeColor = .black - buttonIcon.lineWidth = 1 - - if drawerItem.tag == "notifications" { - buttonIcon.style = .custom(DynamicButtonStyleBell.self) - - cell.customImageView.addSubview(buttonIcon) - } else if drawerItem.tag == "settings" { - buttonIcon.style = .custom(DynamicButtonStyleGear.self) + if #available(iOS 13, *) { + switch drawerItem.tag { + case "notifications": + cell.customImageView.image = UIImage(systemName: "bell") + case "settings": + cell.customImageView.image = UIImage(systemName: "gear") + default: + break + } + } else { + let buttonIcon = DynamicButton(frame: cell.customImageView.bounds) + buttonIcon.bounceButtonOnTouch = false + + buttonIcon.strokeColor = .black + buttonIcon.lineWidth = 1 + + switch drawerItem.tag { + case "notifications": + buttonIcon.style = .custom(DynamicButtonStyleBell.self) + case "settings": + buttonIcon.style = .custom(DynamicButtonStyleGear.self) + default: + break + } cell.customImageView.addSubview(buttonIcon) } } diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index cc54b0357..4457c386e 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -864,7 +864,6 @@ extension OpenHABViewController: ModalHandler { } // MARK: - UISideMenuNavigationControllerDelegate - extension OpenHABViewController: SideMenuNavigationControllerDelegate { func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) { hamburgerButton.setStyle(.arrowRight, animated: animated) diff --git a/openHABTestsSwift/OpenHABUserDefaultsTests.swift b/openHABTestsSwift/OpenHABUserDefaultsTests.swift index 46a37d66b..ac1899363 100644 --- a/openHABTestsSwift/OpenHABUserDefaultsTests.swift +++ b/openHABTestsSwift/OpenHABUserDefaultsTests.swift @@ -25,6 +25,22 @@ class OpenHABUserDefaultsTests: XCTestCase { Preferences.defaultSitemap = Preferences.defaultSitemap } + override func setUp() { + super.setUp() + let defaultsName = Bundle.main.bundleIdentifier! + UserDefaults.standard.removePersistentDomain(forName: defaultsName) + + Preferences.username = Preferences.username + Preferences.localUrl = Preferences.localUrl + Preferences.remoteUrl = Preferences.remoteUrl + Preferences.password = Preferences.password + Preferences.ignoreSSL = Preferences.ignoreSSL + Preferences.demomode = Preferences.demomode + Preferences.idleOff = Preferences.idleOff + Preferences.iconType = Preferences.iconType + Preferences.defaultSitemap = Preferences.defaultSitemap + } + // Testing the consistency between properties of Preferences and the corresponding entry in UserDefaults func testConsistency() { XCTAssertEqual(Preferences.username, UserDefaults.standard.string(forKey: "username")) From ed65fa6aa96481eaf038dbec273e68d403afbb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Mon, 23 Sep 2019 21:36:27 +0200 Subject: [PATCH 10/76] Changing type to UIImageView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/Base.lproj/Main.storyboard | 40 +++++++++++------------------ openHAB/DrawerUITableViewCell.swift | 3 +-- openHAB/OpenHABViewController.swift | 1 + 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/openHAB/Base.lproj/Main.storyboard b/openHAB/Base.lproj/Main.storyboard index 1c75b0511..d9319f08c 100644 --- a/openHAB/Base.lproj/Main.storyboard +++ b/openHAB/Base.lproj/Main.storyboard @@ -58,8 +58,7 @@