From d55ef455646930d27b5ee0940ae3da34d7ad964d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 21 Jun 2020 10:03:48 +0200 Subject: [PATCH 01/78] First attempt with pocketsvg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Podfile | 1 + Podfile.lock | 79 ++++++++++++++--------------- openHAB.xcodeproj/project.pbxproj | 4 ++ openHAB/OpenHABViewController.swift | 6 ++- openHAB/SVGProcessor.swift | 52 +++++++++++++++++++ 5 files changed, 101 insertions(+), 41 deletions(-) create mode 100644 openHAB/SVGProcessor.swift diff --git a/Podfile b/Podfile index 23c057591..f9288bc04 100644 --- a/Podfile +++ b/Podfile @@ -26,6 +26,7 @@ target 'openHAB' do pod 'DynamicButton', '~> 6.2' pod 'SideMenu', '~> 6.4' pod 'Kingfisher', '~> 5.0' + pod 'PocketSVG', '~> 2.0' target 'openHABTestsSwift' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index f1b09d9dc..c94a9e76d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -8,49 +8,46 @@ PODS: - DeviceKit (3.2.0) - DynamicButton (6.2.1) - Fabric (1.10.2) - - Firebase/Analytics (6.24.0): + - Firebase/Analytics (6.27.0): - Firebase/Core - - Firebase/Core (6.24.0): + - Firebase/Core (6.27.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.5.0) - - Firebase/CoreOnly (6.24.0): - - FirebaseCore (= 6.7.0) - - FirebaseAnalytics (6.5.0): - - FirebaseCore (~> 6.7) - - FirebaseInstallations (~> 1.2) - - GoogleAppMeasurement (= 6.5.0) + - FirebaseAnalytics (= 6.6.1) + - Firebase/CoreOnly (6.27.0): + - FirebaseCore (= 6.8.0) + - FirebaseAnalytics (6.6.1): + - FirebaseCore (~> 6.8) + - FirebaseInstallations (~> 1.4) + - GoogleAppMeasurement (= 6.6.1) - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 1.30905.0) - - FirebaseCore (6.7.0): + - FirebaseCore (6.8.0): - FirebaseCoreDiagnostics (~> 1.3) - - FirebaseCoreDiagnosticsInterop (~> 1.2) - GoogleUtilities/Environment (~> 6.5) - GoogleUtilities/Logger (~> 6.5) - - FirebaseCoreDiagnostics (1.3.0): - - FirebaseCoreDiagnosticsInterop (~> 1.2) + - FirebaseCoreDiagnostics (1.4.0): - GoogleDataTransportCCTSupport (~> 3.1) - GoogleUtilities/Environment (~> 6.5) - GoogleUtilities/Logger (~> 6.5) - nanopb (~> 1.30905.0) - - FirebaseCoreDiagnosticsInterop (1.2.0) - - FirebaseInstallations (1.2.0): - - FirebaseCore (~> 6.6) + - FirebaseInstallations (1.4.0): + - FirebaseCore (~> 6.8) - GoogleUtilities/Environment (~> 6.6) - GoogleUtilities/UserDefaults (~> 6.6) - PromisesObjC (~> 1.2) - FlexColorPicker (1.4.2) - Fuzi (3.1.2) - - GoogleAppMeasurement (6.5.0): + - GoogleAppMeasurement (6.6.1): - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 1.30905.0) - - GoogleDataTransport (6.1.0) - - GoogleDataTransportCCTSupport (3.1.0): + - GoogleDataTransport (6.2.1) + - GoogleDataTransportCCTSupport (3.2.0): - GoogleDataTransport (~> 6.1) - nanopb (~> 1.30905.0) - GoogleUtilities/AppDelegateSwizzler (6.6.0): @@ -72,21 +69,22 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.6.0): - GoogleUtilities/Logger - - Kingfisher (5.13.4): - - Kingfisher/Core (= 5.13.4) - - Kingfisher/Core (5.13.4) - - Kingfisher/SwiftUI (5.13.4): + - Kingfisher (5.14.0): + - Kingfisher/Core (= 5.14.0) + - Kingfisher/Core (5.14.0) + - Kingfisher/SwiftUI (5.14.0): - Kingfisher/Core - nanopb (1.30905.0): - nanopb/decode (= 1.30905.0) - nanopb/encode (= 1.30905.0) - nanopb/decode (1.30905.0) - nanopb/encode (1.30905.0) - - PromisesObjC (1.2.8) + - PocketSVG (2.5.0) + - PromisesObjC (1.2.9) - SideMenu (6.4.8) - SVGKit (2.1.1): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.44.9) + - SwiftFormat/CLI (0.44.13) - SwiftLint (0.39.2) - SwiftMessages (7.0.1): - SwiftMessages/App (= 7.0.1) @@ -103,6 +101,7 @@ DEPENDENCIES: - Fuzi (~> 3.1) - Kingfisher (~> 5.0) - Kingfisher/SwiftUI (~> 5.0) + - PocketSVG (~> 2.0) - SideMenu (~> 6.4) - SVGKit - SwiftFormat/CLI @@ -121,7 +120,6 @@ SPEC REPOS: - FirebaseAnalytics - FirebaseCore - FirebaseCoreDiagnostics - - FirebaseCoreDiagnosticsInterop - FirebaseInstallations - FlexColorPicker - Fuzi @@ -131,6 +129,7 @@ SPEC REPOS: - GoogleUtilities - Kingfisher - nanopb + - PocketSVG - PromisesObjC - SideMenu - SVGKit @@ -145,27 +144,27 @@ SPEC CHECKSUMS: DeviceKit: d081659419cce07c0b5239dbc9fb39ed7413c7fe DynamicButton: 95f30460793bd3510a5c213ac1b810a5e3d54b6a Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 - Firebase: b28e55c60efd98963cd9011fe2fac5a10c2ba124 - FirebaseAnalytics: 7386fc2176e3f93ad8ef34b5b1f2b33a891e4962 - FirebaseCore: e610482f64097b0e9f056cd97bc6b33dfabcbb6a - FirebaseCoreDiagnostics: 4a773a47bd83bbd5a9b1ccf1ce7caa8b2d535e67 - FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850 - FirebaseInstallations: 2119fb3e46b0a88bfdbf12562f855ee3252462fa + Firebase: fc4cbf6f1592636431821ef9a3c557e4dfd9f268 + FirebaseAnalytics: 0ea640473474f036cabbc2576e20c2d63671c92f + FirebaseCore: feda061cb1ee6d8ad4824f4a4a8ffbcfe284f595 + FirebaseCoreDiagnostics: 4505e4d4009b1d93f605088ee7d7764d5f0d1c84 + FirebaseInstallations: 293f567159b6d66d1c990f13bb868066096c94ec FlexColorPicker: d7ed5cfd8ceb936f2930e4e30629f9448967a5f8 Fuzi: dba7215e52fb39dd7b1a62f69ede1e30edff0ae1 - GoogleAppMeasurement: 4c644d86835d827bab30ab6aabb9ecaf1f500735 - GoogleDataTransport: f6f8eba931df03ebd2232ff4645aa85f8f47b5ab - GoogleDataTransportCCTSupport: d70a561f7d236af529fee598835caad5e25f6d3d + GoogleAppMeasurement: 2fd5c5a56c069db635c8e7b92d4809a9591d0a69 + GoogleDataTransport: 9a8a16f79feffc7f42096743de2a7c4815e84020 + GoogleDataTransportCCTSupport: 489c1265d2c85b68187a83a911913d190012158d GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 - Kingfisher: d2279a7abece3c7f25a80cd2b7f363ca5cf3f44c + Kingfisher: 7b64389a43139c903ec434788344c288217c792d nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 - PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6 + PocketSVG: 9d9c4bc8e7d8dbbc208bd21e5c92814fd3c6c34d + PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 SideMenu: 4a891be552d30bb6fa87ad404d62e485f8450c34 SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac - SwiftFormat: e415b539c50e7a956a44b023544c9846c0c037d7 + SwiftFormat: 87e745cb2f6509894a44ac4f311a8722a9ebcb8b SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 SwiftMessages: b577dc7043be8b299857ab35bb663dbff6483bd0 -PODFILE CHECKSUM: ba32ee2afd2062b9d8b4772a91878dd85b5a8245 +PODFILE CHECKSUM: 06ea1c3791eddb2dd174f3d547559ec7f5a1c4d7 -COCOAPODS: 1.9.1 +COCOAPODS: 1.9.2 diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 37f3cc4c2..0289bfc15 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -129,6 +129,7 @@ DAEAA89D21E6B06400267EA3 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89C21E6B06300267EA3 /* ReusableView.swift */; }; DAEAA89F21E6B16600267EA3 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89E21E6B16600267EA3 /* UITableView.swift */; }; DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAED514E2305CDE3003BCB31 /* XMLData.swift */; }; + DAED69D1249F4029007E0046 /* SVGProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAED69D0249F4029007E0046 /* SVGProcessor.swift */; }; DAF4578223D630C70018B495 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF4578123D630C70018B495 /* IconView.swift */; }; DAF4578523D7807A0018B495 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 934B610B2348D2F9009112D5 /* Color+Extension.swift */; }; DAF4578723D798A50018B495 /* TextLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF4578623D798A50018B495 /* TextLabelView.swift */; }; @@ -432,6 +433,7 @@ DAEAA89C21E6B06300267EA3 /* ReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReusableView.swift; sourceTree = ""; }; DAEAA89E21E6B16600267EA3 /* UITableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = ""; }; DAED514E2305CDE3003BCB31 /* XMLData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLData.swift; sourceTree = ""; }; + DAED69D0249F4029007E0046 /* SVGProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVGProcessor.swift; sourceTree = ""; }; DAF4578123D630C70018B495 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; DAF4578323D780730018B495 /* UIColorExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtension.swift; sourceTree = ""; }; DAF4578623D798A50018B495 /* TextLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLabelView.swift; sourceTree = ""; }; @@ -933,6 +935,7 @@ DAEAA89E21E6B16600267EA3 /* UITableView.swift */, DA7E1E47222EB00B002AEFD8 /* PlayerView.swift */, DA21EAE12339621C001AB415 /* Throttler.swift */, + DAED69D0249F4029007E0046 /* SVGProcessor.swift */, ); name = Widgets; sourceTree = ""; @@ -1732,6 +1735,7 @@ DAA42BAA21DC983B00244B2A /* VideoUITableViewCell.swift in Sources */, DFB2623B18830A3600D3244D /* AppDelegate.swift in Sources */, DF4B84041885A53700F34902 /* OpenHABDataObject.swift in Sources */, + DAED69D1249F4029007E0046 /* SVGProcessor.swift in Sources */, DAC65FC7236EDF3900F4501E /* SpinnerViewController.swift in Sources */, DF4A02421CF34096006C3456 /* OpenHABDrawerItem.swift in Sources */, DF4A022C1CF315BA006C3456 /* OpenHABDrawerTableViewController.swift in Sources */, diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index a924a3933..ebc6944c1 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1057,9 +1057,13 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { placeholder: UIImage(named: "blankicon.png"), completionHandler: reportOnResults) case .svg: +// cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), +// placeholder: UIImage(named: "blankicon.png"), +// options: [.processor(SVGProcessor())], +// completionHandler: reportOnResults) cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), placeholder: UIImage(named: "blankicon.png"), - options: [.processor(SVGProcessor())], + options: [.processor(SVGPocketProcessor(size: cell.imageView?.frame.size ?? CGSize(width: 10, height: 10)))], completionHandler: reportOnResults) } } diff --git a/openHAB/SVGProcessor.swift b/openHAB/SVGProcessor.swift new file mode 100644 index 000000000..a9488bc88 --- /dev/null +++ b/openHAB/SVGProcessor.swift @@ -0,0 +1,52 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import Kingfisher +import PocketSVG + +struct SVGPocketProcessor: 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 = "svgprocessor" + var size: CGSize! + init(size: CGSize) { + self.size = size + } + + // Convert input data/image to target image and return it. + func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? { + switch item { + case let .image(image): + return image + case let .data(data): + if let svgString = String(data: data, encoding: .utf8) { + let paths = SVGBezierPath.paths(fromSVGString: svgString) + let layer = SVGLayer() + layer.paths = paths + let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) + layer.frame = frame + let img = snapshotImage(for: layer) + return img + } + return nil + } + } + + func snapshotImage(for view: CALayer) -> UIImage? { + UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale) + guard let context = UIGraphicsGetCurrentContext() else { return nil } + view.render(in: context) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image + } +} From c722d044ffdb2ac6c9f53cb0f726f5ee8953747e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 19 Jul 2020 17:01:36 +0200 Subject: [PATCH 02/78] Committing before moving away --- Podfile | 5 +++-- Podfile.lock | 29 +++++++++++++++++------------ openHAB/OpenHABViewController.swift | 10 +++++----- openHAB/SVGProcessor.swift | 25 ++++++++++++++----------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Podfile b/Podfile index f9288bc04..da4ac61f8 100644 --- a/Podfile +++ b/Podfile @@ -14,7 +14,7 @@ target 'openHAB' do shared_pods pod 'SwiftFormat/CLI' pod 'SwiftLint' - pod 'SVGKit' + pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '3.x' pod 'Fabric', '~> 1.7' pod 'Crashlytics', '~> 3.9' @@ -26,7 +26,8 @@ target 'openHAB' do pod 'DynamicButton', '~> 6.2' pod 'SideMenu', '~> 6.4' pod 'Kingfisher', '~> 5.0' - pod 'PocketSVG', '~> 2.0' + #pod "Macaw", "0.9.6" + #pod 'SwiftSVG', '~> 2.0' target 'openHABTestsSwift' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index c94a9e76d..a65599b3f 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -79,12 +79,11 @@ PODS: - nanopb/encode (= 1.30905.0) - nanopb/decode (1.30905.0) - nanopb/encode (1.30905.0) - - PocketSVG (2.5.0) - PromisesObjC (1.2.9) - SideMenu (6.4.8) - - SVGKit (2.1.1): + - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.44.13) + - SwiftFormat/CLI (0.44.14) - SwiftLint (0.39.2) - SwiftMessages (7.0.1): - SwiftMessages/App (= 7.0.1) @@ -101,9 +100,8 @@ DEPENDENCIES: - Fuzi (~> 3.1) - Kingfisher (~> 5.0) - Kingfisher/SwiftUI (~> 5.0) - - PocketSVG (~> 2.0) - SideMenu (~> 6.4) - - SVGKit + - SVGKit (from `https://github.com/SVGKit/SVGKit.git`, branch `3.x`) - SwiftFormat/CLI - SwiftLint - SwiftMessages @@ -129,14 +127,22 @@ SPEC REPOS: - GoogleUtilities - Kingfisher - nanopb - - PocketSVG - PromisesObjC - SideMenu - - SVGKit - SwiftFormat - SwiftLint - SwiftMessages +EXTERNAL SOURCES: + SVGKit: + :branch: 3.x + :git: https://github.com/SVGKit/SVGKit.git + +CHECKOUT OPTIONS: + SVGKit: + :commit: 2a4068f0ea546dcd82f7e4dd9aa9026c0a0a2235 + :git: https://github.com/SVGKit/SVGKit.git + SPEC CHECKSUMS: Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 CocoaLumberjack: b17ae15142558d08bbacf69775fa10c4abbebcc9 @@ -157,14 +163,13 @@ SPEC CHECKSUMS: GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 Kingfisher: 7b64389a43139c903ec434788344c288217c792d nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 - PocketSVG: 9d9c4bc8e7d8dbbc208bd21e5c92814fd3c6c34d PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 SideMenu: 4a891be552d30bb6fa87ad404d62e485f8450c34 - SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac - SwiftFormat: 87e745cb2f6509894a44ac4f311a8722a9ebcb8b + SVGKit: c6fe3403caafbd20d4ad5a5cc7dcae6115b3c6e1 + SwiftFormat: a5ab293a7f6a812bec6f4ffc5507b7ed08f7f6e1 SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 SwiftMessages: b577dc7043be8b299857ab35bb663dbff6483bd0 -PODFILE CHECKSUM: 06ea1c3791eddb2dd174f3d547559ec7f5a1c4d7 +PODFILE CHECKSUM: c2a5a545af2eb4e0cc66d2ee9aa3b6a5dc5c4512 -COCOAPODS: 1.9.2 +COCOAPODS: 1.9.3 diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index ebc6944c1..b4b633fad 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1057,14 +1057,14 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { placeholder: UIImage(named: "blankicon.png"), completionHandler: reportOnResults) case .svg: -// cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), -// placeholder: UIImage(named: "blankicon.png"), -// options: [.processor(SVGProcessor())], -// completionHandler: reportOnResults) cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), placeholder: UIImage(named: "blankicon.png"), - options: [.processor(SVGPocketProcessor(size: cell.imageView?.frame.size ?? CGSize(width: 10, height: 10)))], + options: [.processor(SVGProcessor())], completionHandler: reportOnResults) +// cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), +// placeholder: UIImage(named: "blankicon.png"), +// options: [.processor(SVGPocketProcessor(size: cell.imageView?.frame.size ?? CGSize(width: 10, height: 10)))], +// completionHandler: reportOnResults) } } } diff --git a/openHAB/SVGProcessor.swift b/openHAB/SVGProcessor.swift index a9488bc88..18b675f7c 100644 --- a/openHAB/SVGProcessor.swift +++ b/openHAB/SVGProcessor.swift @@ -11,9 +11,9 @@ import Foundation import Kingfisher -import PocketSVG +// import Macaw -struct SVGPocketProcessor: ImageProcessor { +struct SVGMacawProcessor: 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 = "svgprocessor" @@ -28,15 +28,18 @@ struct SVGPocketProcessor: ImageProcessor { case let .image(image): return image case let .data(data): - if let svgString = String(data: data, encoding: .utf8) { - let paths = SVGBezierPath.paths(fromSVGString: svgString) - let layer = SVGLayer() - layer.paths = paths - let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) - layer.frame = frame - let img = snapshotImage(for: layer) - return img - } +// if let svgString = String(data: data, encoding: .utf8) { +// UIImageView(i) +// let node = try! SVGParser.parse(text: svgString) +// +// let paths = SVGBezierPath.paths(fromSVGString: svgString) +// let layer = SVGLayer() +// layer.paths = paths +// let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) +// layer.frame = frame +// let img = snapshotImage(for: layer) +// return img +// } return nil } } From 0b94f459f32edd243932803438c789bad8536479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 31 Jul 2020 19:33:48 +0200 Subject: [PATCH 03/78] Introduced enums ItemType/WidgetType to OpenHABItem.type, OpenHABItem.groupType, OpenHABWidget.type Introduced NumberState to hold value, unit and format Inspired by kotlin app Extended parsing of JSON properties to complete feature set and for instance handle visibility, switchSupport (tbd) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Error correction: minimumFractionDigits in valueText Fix for #554 (to be extended beyond Setpoint) Signed-off-by: Tim Müller-Seydlitz --- openHAB.xcodeproj/project.pbxproj | 16 ++- openHAB/NewImageUITableViewCell.swift | 14 +-- openHAB/OpenHABViewController.swift | 44 +++---- openHAB/SVGProcessor.swift | 55 --------- openHAB/SetpointUITableViewCell.swift | 50 +++----- openHABCore/Sources/Model/NumberState.swift | 50 ++++++++ openHABCore/Sources/Model/OpenHABItem.swift | 115 ++++++++++++++---- .../Model/OpenHABStateDescription.swift | 24 +++- openHABCore/Sources/Model/OpenHABWidget.swift | 106 ++++++++++++++-- .../Sources/Util/DoubleExtension.swift | 1 + openHABCore/Sources/Util/Endpoint.swift | 4 +- .../Sources/Util/StringExtension.swift | 87 +++++++++++++ openHABTestsSwift/NumberStateTest.swift | 65 ++++++++++ openHABTestsSwift/OpenHABXMLParserTests.swift | 5 +- openHABTestsSwift/restAPI.json | 31 +++++ .../Views/ContentView.swift | 2 +- .../Views/Rows/ImageRawRow.swift | 2 +- .../Model/ObservableOpenHABWidget.swift | 11 +- 18 files changed, 507 insertions(+), 175 deletions(-) delete mode 100644 openHAB/SVGProcessor.swift create mode 100644 openHABCore/Sources/Model/NumberState.swift create mode 100644 openHABTestsSwift/NumberStateTest.swift create mode 100644 openHABTestsSwift/restAPI.json diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 0289bfc15..7fe0a85b6 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -124,12 +124,14 @@ DAC6608D236F771600F4501E /* PreferencesSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608C236F771600F4501E /* PreferencesSwiftUIView.swift */; }; DAC6608F236F80BA00F4501E /* PreferencesRowUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */; }; DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */; }; + DACC72E224D00D59007EFAE3 /* NumberStateTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */; }; + DADC1EAD24D2CB8B0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; + DADC1EAE24D2CB8C0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; DAE249A223EE07C800986877 /* Future.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE249A023EE07C800986877 /* Future.swift */; }; DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */; }; DAEAA89D21E6B06400267EA3 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89C21E6B06300267EA3 /* ReusableView.swift */; }; DAEAA89F21E6B16600267EA3 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89E21E6B16600267EA3 /* UITableView.swift */; }; DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAED514E2305CDE3003BCB31 /* XMLData.swift */; }; - DAED69D1249F4029007E0046 /* SVGProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAED69D0249F4029007E0046 /* SVGProcessor.swift */; }; DAF4578223D630C70018B495 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF4578123D630C70018B495 /* IconView.swift */; }; DAF4578523D7807A0018B495 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 934B610B2348D2F9009112D5 /* Color+Extension.swift */; }; DAF4578723D798A50018B495 /* TextLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF4578623D798A50018B495 /* TextLabelView.swift */; }; @@ -428,12 +430,14 @@ DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesRowUIView.swift; sourceTree = ""; }; DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABWatchTests.swift; sourceTree = ""; }; DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCaseExtension.swift; sourceTree = ""; }; + DACC72E024CE14FB007EFAE3 /* restAPI.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = restAPI.json; sourceTree = ""; }; + DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberStateTest.swift; sourceTree = ""; }; + DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberState.swift; sourceTree = ""; }; DAE249A023EE07C800986877 /* Future.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Future.swift; path = openHABCore/Sources/Util/Future.swift; sourceTree = SOURCE_ROOT; }; DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABNotificationsViewController.swift; sourceTree = ""; }; DAEAA89C21E6B06300267EA3 /* ReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReusableView.swift; sourceTree = ""; }; DAEAA89E21E6B16600267EA3 /* UITableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = ""; }; DAED514E2305CDE3003BCB31 /* XMLData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLData.swift; sourceTree = ""; }; - DAED69D0249F4029007E0046 /* SVGProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVGProcessor.swift; sourceTree = ""; }; DAF4578123D630C70018B495 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; DAF4578323D780730018B495 /* UIColorExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtension.swift; sourceTree = ""; }; DAF4578623D798A50018B495 /* TextLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLabelView.swift; sourceTree = ""; }; @@ -670,6 +674,7 @@ 9350F16E23814F2500054BA8 /* OpenHABStateDescription.swift */, 9350F16823814EF500054BA8 /* OpenHABWidget.swift */, 9350F16B23814F0D00054BA8 /* OpenHABWidgetMapping.swift */, + DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */, ); path = Model; sourceTree = ""; @@ -818,6 +823,8 @@ DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */, DA2DC23321F2736C00830730 /* Info.plist */, DA966477232EDEAD00CB418B /* MockURLProtocol.swift */, + DACC72E024CE14FB007EFAE3 /* restAPI.json */, + DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */, ); path = openHABTestsSwift; sourceTree = ""; @@ -935,7 +942,6 @@ DAEAA89E21E6B16600267EA3 /* UITableView.swift */, DA7E1E47222EB00B002AEFD8 /* PlayerView.swift */, DA21EAE12339621C001AB415 /* Throttler.swift */, - DAED69D0249F4029007E0046 /* SVGProcessor.swift */, ); name = Widgets; sourceTree = ""; @@ -1622,6 +1628,7 @@ 9350F10423814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F191238151CE00054BA8 /* StringExtension.swift in Sources */, 9350F18B2381519300054BA8 /* ClientCertificateManager.swift in Sources */, + DADC1EAD24D2CB8B0052B8D4 /* NumberState.swift in Sources */, 9350F1852381516300054BA8 /* KeyedDecodingContainerProtocolExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1654,6 +1661,7 @@ 9350F10523814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F192238151CE00054BA8 /* StringExtension.swift in Sources */, 9350F18C2381519300054BA8 /* ClientCertificateManager.swift in Sources */, + DADC1EAE24D2CB8C0052B8D4 /* NumberState.swift in Sources */, 9350F1862381516300054BA8 /* KeyedDecodingContainerProtocolExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1712,6 +1720,7 @@ DAB9C7B1230B323000A7DB6E /* OpenHABXMLParserTests.swift in Sources */, DA19E25B22FD801D002F8F2F /* OpenHABGeneralTests.swift in Sources */, DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */, + DACC72E224D00D59007EFAE3 /* NumberStateTest.swift in Sources */, DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */, DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */, DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */, @@ -1735,7 +1744,6 @@ DAA42BAA21DC983B00244B2A /* VideoUITableViewCell.swift in Sources */, DFB2623B18830A3600D3244D /* AppDelegate.swift in Sources */, DF4B84041885A53700F34902 /* OpenHABDataObject.swift in Sources */, - DAED69D1249F4029007E0046 /* SVGProcessor.swift in Sources */, DAC65FC7236EDF3900F4501E /* SpinnerViewController.swift in Sources */, DF4A02421CF34096006C3456 /* OpenHABDrawerItem.swift in Sources */, DF4A022C1CF315BA006C3456 /* OpenHABDrawerTableViewController.swift in Sources */, diff --git a/openHAB/NewImageUITableViewCell.swift b/openHAB/NewImageUITableViewCell.swift index dc30f9724..c6926c740 100644 --- a/openHAB/NewImageUITableViewCell.swift +++ b/openHAB/NewImageUITableViewCell.swift @@ -40,9 +40,9 @@ class NewImageUITableViewCell: GenericUITableViewCell { guard let widget = widget else { return .empty } switch widget.type { - case "Chart": + case .chart: return .link(url: Endpoint.chart(rootUrl: appData!.openHABRootUrl, period: widget.period, type: widget.item?.type, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: chartStyle).url) - case "Image": + case .image: if let item = widget.item { return widgetPayload(fromItem: item) } @@ -79,7 +79,7 @@ class NewImageUITableViewCell: GenericUITableViewCell { super.traitCollectionDidChange(previousTraitCollection) chartStyle = OHInterfaceStyle.current == .light ? ChartStyle.light : ChartStyle.dark - if widget.type == "Chart" { + if widget.type == .chart { loadImage() } } @@ -127,14 +127,14 @@ class NewImageUITableViewCell: GenericUITableViewCell { private func widgetPayload(fromItem item: OpenHABItem) -> ImageType { switch item.type { - case "Image": + case .image: os_log("Image base64Encoded.", log: .urlComposition, type: .debug) - guard let data = item.state.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters) else { + guard let data = item.state?.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters) else { return .empty } return .embedded(image: UIImage(data: decodedData)) - case "String": - return .link(url: URL(string: item.state)) + case .stringItem: + return .link(url: URL(string: item.state ?? "")) default: return .empty } diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index b4b633fad..fef2bf0ba 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -663,7 +663,7 @@ class OpenHABViewController: UIViewController { guard let searchText = searchText else { return } filteredPage = currentPage?.filter { - $0.label.lowercased().contains(searchText.lowercased()) && $0.type != "Frame" + $0.label.lowercased().contains(searchText.lowercased()) && $0.type != .frame } filteredPage?.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) @@ -964,14 +964,14 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let widget: OpenHABWidget? = relevantPage?.widgets[indexPath.row] switch widget?.type { - case "Frame": + case .frame: return widget?.label.count ?? 0 > 0 ? 35.0 : 0 - case "Image", "Chart", "Video": + case .image, .chart, .video: return UITableView.automaticDimension - case "Webview", "Mapview": - if let height = widget?.height, Int(height) != 0 { + case .webview, .mapview: + if let height = widget?.height { // calculate webview/mapview height and return it - let heightValue = (Double(height) ?? 0.0) * 44 + let heightValue = height * 44 os_log("Webview/Mapview height would be %g", log: .viewCycle, type: .info, heightValue) return CGFloat(heightValue) } else { @@ -988,44 +988,44 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { let cell: UITableViewCell switch widget?.type { - case "Frame": + case .frame: cell = tableView.dequeueReusableCell(for: indexPath) as FrameUITableViewCell - case "Switch": + case .switchWidget: // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 if widget?.mappings.count ?? 0 > 0 { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell // RollershutterItem changed to Rollershutter in later builds of OH2 - } else if let type = widget?.item?.type, type == "Switch" { + } else if let type = widget?.item?.type, type == .switchItem { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell - } else if let type = widget?.item?.type, type.isAny(of: "RollershutterItem", "Rollershutter") || (type == "Group" && widget?.item?.groupType == "Rollershutter") { + } else if let type = widget?.item?.type, type == .rollershutter || (type == .group && widget?.item?.groupType == .rollershutter) { cell = tableView.dequeueReusableCell(for: indexPath) as RollershutterUITableViewCell } else if widget?.item?.stateDescription?.options.count ?? 0 > 0 { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell } else { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell } - case "Setpoint": + case .setpoint: cell = tableView.dequeueReusableCell(for: indexPath) as SetpointUITableViewCell - case "Slider": + case .slider: cell = tableView.dequeueReusableCell(for: indexPath) as SliderUITableViewCell - case "Selection": + case .selection: cell = tableView.dequeueReusableCell(for: indexPath) as SelectionUITableViewCell - case "Colorpicker": + case .colorpicker: cell = tableView.dequeueReusableCell(for: indexPath) as ColorPickerUITableViewCell (cell as? ColorPickerUITableViewCell)?.delegate = self - case "Image", "Chart": + case .image, .chart: cell = tableView.dequeueReusableCell(withIdentifier: openHABViewControllerImageViewCellReuseIdentifier, for: indexPath) as! NewImageUITableViewCell (cell as? NewImageUITableViewCell)?.didLoad = { [weak self] in self?.updateWidgetTableView() } - case "Video": + case .video: cell = tableView.dequeueReusableCell(withIdentifier: "VideoUITableViewCell", for: indexPath) as! VideoUITableViewCell (cell as? VideoUITableViewCell)?.didLoad = { [weak self] in self?.updateWidgetTableView() } - case "Webview": + case .webview: cell = tableView.dequeueReusableCell(for: indexPath) as WebUITableViewCell - case "Mapview": + case .mapview: cell = (tableView.dequeueReusableCell(withIdentifier: openHABViewControllerMapViewCellReuseIdentifier) as? MapViewTableViewCell)! default: cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell @@ -1083,9 +1083,9 @@ 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") { + if let type = nextWidget?.type, type.isAny(of: .frame, .image, .video, .webview, .chart) { cell.separatorInset = UIEdgeInsets.zero - } else if !(widget?.type == "Frame") { + } else if !(widget?.type == .frame) { cell.separatorInset = UIEdgeInsets(top: 0, left: 60, bottom: 0, right: 0) } } @@ -1115,7 +1115,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { newViewController.pageUrl = widget?.linkedPage?.link ?? "" newViewController.openHABRootUrl = openHABRootUrl navigationController?.pushViewController(newViewController, animated: true) - } else if widget?.type == "Selection" { + } else if widget?.type == .selection { os_log("Selected selection widget", log: .viewCycle, type: .info) selectedWidgetRow = indexPath.row @@ -1143,7 +1143,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { @available(iOS 13.0, *) func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { - if let cell = tableView.cellForRow(at: indexPath) as? GenericUITableViewCell, cell.widget.type == "Text", let text = cell.widget?.labelValue ?? cell.widget?.labelText, !text.isEmpty { + if let cell = tableView.cellForRow(at: indexPath) as? GenericUITableViewCell, cell.widget.type == .text, let text = cell.widget?.labelValue ?? cell.widget?.labelText, !text.isEmpty { return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in let copy = UIAction(title: "Copy item label", image: UIImage(systemName: "square.and.arrow.up")) { _ in UIPasteboard.general.string = text diff --git a/openHAB/SVGProcessor.swift b/openHAB/SVGProcessor.swift deleted file mode 100644 index 18b675f7c..000000000 --- a/openHAB/SVGProcessor.swift +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2010-2020 Contributors to the openHAB project -// -// See the NOTICE file(s) distributed with this work for additional -// information. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0 -// -// SPDX-License-Identifier: EPL-2.0 - -import Foundation -import Kingfisher -// import Macaw - -struct SVGMacawProcessor: 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 = "svgprocessor" - var size: CGSize! - init(size: CGSize) { - self.size = size - } - - // Convert input data/image to target image and return it. - func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? { - switch item { - case let .image(image): - return image - case let .data(data): -// if let svgString = String(data: data, encoding: .utf8) { -// UIImageView(i) -// let node = try! SVGParser.parse(text: svgString) -// -// let paths = SVGBezierPath.paths(fromSVGString: svgString) -// let layer = SVGLayer() -// layer.paths = paths -// let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) -// layer.frame = frame -// let img = snapshotImage(for: layer) -// return img -// } - return nil - } - } - - func snapshotImage(for view: CALayer) -> UIImage? { - UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale) - guard let context = UIGraphicsGetCurrentContext() else { return nil } - view.render(in: context) - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - return image - } -} diff --git a/openHAB/SetpointUITableViewCell.swift b/openHAB/SetpointUITableViewCell.swift index 9e04c2753..82bf0126b 100644 --- a/openHAB/SetpointUITableViewCell.swift +++ b/openHAB/SetpointUITableViewCell.swift @@ -42,45 +42,27 @@ class SetpointUITableViewCell: GenericUITableViewCell { super.displayWidget() } + private func handleUpDown(down: Bool) { + var numberState = widget?.stateValueAsNumberState + let stateValue = numberState?.value ?? widget.minValue + let newValue: Double + switch down { + case true: newValue = stateValue - widget.step + case false: newValue = stateValue + widget.step + } + if newValue >= widget.minValue, newValue <= widget.maxValue { + numberState?.value = newValue + widget.sendItemUpdate(state: numberState) + } + } + @objc func decreaseValue(_ sender: Any?) { - os_log("down button pressed", log: .viewCycle, type: .info) - - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() - widget.step - newValue = max(newValue, widget.minValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() - Int(widget.step) - newValue = max(newValue, Int(widget.minValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + handleUpDown(down: true) } @objc func increaseValue(_ sender: Any?) { - os_log("up button pressed", log: .viewCycle, type: .info) - - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() + widget.step - newValue = min(newValue, widget.maxValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() + Int(widget.step) - newValue = min(newValue, Int(widget.maxValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + handleUpDown(down: false) } } diff --git a/openHABCore/Sources/Model/NumberState.swift b/openHABCore/Sources/Model/NumberState.swift new file mode 100644 index 000000000..57cc32ad9 --- /dev/null +++ b/openHABCore/Sources/Model/NumberState.swift @@ -0,0 +1,50 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +public struct NumberState: CustomStringConvertible, Equatable { + public var description: String { + toString(locale: Locale.current) + } + + public var value: Double + var unit: String? = "" + var format: String? = "" + + func toString(locale: Locale?) -> String { + if let format = format, format.isEmpty == false { + let actualFormat = format.replacingOccurrences(of: "%unit%", with: unit ?? "") + if format.contains("%d") == true { + return String(format: actualFormat, locale: locale, Int(value)) + } else { + return String(format: actualFormat, locale: locale, value) + } + } + if let unit = unit, unit.isEmpty == false { + return "\(formatValue()) \(unit)" + } else { + return formatValue() + } + } + + func formatValue() -> String { + String(value) + } + + private func getActualValue() -> NSNumber { + if format?.contains("%d") == true { + return NSNumber(value: Int(value)) + } else { + return NSNumber(value: value) + } + } +} diff --git a/openHABCore/Sources/Model/OpenHABItem.swift b/openHABCore/Sources/Model/OpenHABItem.swift index 9640acdb0..cbe2f0ea5 100644 --- a/openHABCore/Sources/Model/OpenHABItem.swift +++ b/openHABCore/Sources/Model/OpenHABItem.swift @@ -13,24 +13,33 @@ import CoreLocation import Fuzi import os.log import UIKit - public final class OpenHABItem: NSObject, CommItem { - public var type = "" - public var groupType = "" + public var type: ItemType? + public var groupType: ItemType? public var name = "" - public var state = "" + public var state: String? public var link = "" public var label = "" public var stateDescription: OpenHABStateDescription? + public var readOnly = false + public var members: [OpenHABItem] = [] + public var category = "" - public init(name: String, type: String, state: String, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?) { + public init(name: String, type: String, state: String?, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?, members: [OpenHABItem], category: String?) { self.name = name - self.type = type - self.state = state + self.type = type.toItemType() + if let state = state, (state == "NULL" || state == "UNDEF" || state.caseInsensitiveCompare("undefined") == .orderedSame) { + self.state = nil + } else { + self.state = state + } self.link = link self.label = label ?? "" - self.groupType = groupType ?? "" + self.groupType = groupType?.toItemType() self.stateDescription = stateDescription + readOnly = stateDescription?.readOnly ?? false + self.members = members + self.category = category ?? "" } public init(xml xmlElement: XMLElement) { @@ -38,8 +47,8 @@ public final class OpenHABItem: NSObject, CommItem { for child in xmlElement.children { switch child.tag { case "name": name = child.stringValue - case "type": type = child.stringValue - case "groupType": groupType = child.stringValue + case "type": type = child.stringValue.toItemType() + case "groupType": groupType = child.stringValue.toItemType() case "state": state = child.stringValue case "link": link = child.stringValue default: @@ -47,21 +56,67 @@ public final class OpenHABItem: NSObject, CommItem { } } } + + func isOfTypeOrGroupType(_ type: ItemType) -> Bool { + self.type == type || groupType == type + } + + var canBeToggled: Bool { + isOfTypeOrGroupType(ItemType.color) || + isOfTypeOrGroupType(ItemType.contact) || + isOfTypeOrGroupType(ItemType.dimmer) || + isOfTypeOrGroupType(ItemType.rollershutter) || + isOfTypeOrGroupType(ItemType.switchItem) || + isOfTypeOrGroupType(ItemType.player) + } +} + +extension String { + public func stateAsDouble() -> Double { + numberValue?.doubleValue ?? 0 + } + + public func stateAsUIColor() -> UIColor { + if self == "Uninitialized" { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } else { + let values = components(separatedBy: ",") + if values.count == 3 { + let hue = CGFloat(state: values[0], divisor: 360) + let saturation = CGFloat(state: values[1], divisor: 100) + let brightness = CGFloat(state: values[2], divisor: 100) + os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) + return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) + } else { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } + } + } + + public func stateAsLocation() -> CLLocation { + // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') + let locationComponents = components(separatedBy: ",") + if locationComponents.count >= 2 { + let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) + let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) + + return CLLocation(latitude: latitude, longitude: longitude) + } + return CLLocation(latitude: 0.0, longitude: 0.0) + } } extension OpenHABItem { public func stateAsDouble() -> Double { - state.numberValue?.doubleValue ?? 0 + state?.numberValue?.doubleValue ?? 0 } public func stateAsInt() -> Int { - state.numberValue?.intValue ?? 0 + state?.numberValue?.intValue ?? 0 } public func stateAsUIColor() -> UIColor { - if state == "Uninitialized" { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } else { + if let state = state { let values = state.components(separatedBy: ",") if values.count == 3 { let hue = CGFloat(state: values[0], divisor: 360) @@ -72,18 +127,24 @@ extension OpenHABItem { } else { return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) } + } else { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) } } public func stateAsLocation() -> CLLocation? { - if type == "Location" { - // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') - let locationComponents = state.components(separatedBy: ",") - if locationComponents.count >= 2 { - let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) - let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) - - return CLLocation(latitude: latitude, longitude: longitude) + if type == .location { + // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') + if let state = state { + let locationComponents = state.components(separatedBy: ",") + if locationComponents.count >= 2 { + let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) + let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) + + return CLLocation(latitude: latitude, longitude: longitude) + } + } else { + return nil } } return nil @@ -96,15 +157,19 @@ extension OpenHABItem { let groupType: String? let name: String let link: String - let state: String + let state: String? let label: String? let stateDescription: OpenHABStateDescription.CodingData? + let members: [OpenHABItem.CodingData]? + let category: String? } } extension OpenHABItem.CodingData { public var openHABItem: OpenHABItem { - OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription) + let mappedMembers = members?.map { $0.openHABItem } ?? [] + + return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, members: mappedMembers, category: category) } } diff --git a/openHABCore/Sources/Model/OpenHABStateDescription.swift b/openHABCore/Sources/Model/OpenHABStateDescription.swift index 950918b39..ee126ac50 100644 --- a/openHABCore/Sources/Model/OpenHABStateDescription.swift +++ b/openHABCore/Sources/Model/OpenHABStateDescription.swift @@ -19,12 +19,31 @@ public class OpenHABStateDescription { public var options: [OpenHABOptions] = [] - init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?) { + public var numberPattern: String? + + init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?, pattern: String?) { self.minimum = minimum ?? 0.0 self.maximum = maximum ?? 100.0 self.step = step ?? 1.0 self.readOnly = readOnly ?? false self.options = options ?? [] + + // Remove transformation instructions (e.g. for 'MAP(foo.map):%s' keep only '%s') + + let regexPattern = #"^[A-Z]+(\(.*\))?:(.*)$"# + let regex = try? NSRegularExpression(pattern: regexPattern, options: .caseInsensitive) + if let pattern = pattern { + let nsrange = NSRange(pattern.startIndex ..< pattern.endIndex, in: pattern) + if let match = regex?.firstMatch(in: pattern, options: [], range: nsrange) { + if let range = Range(match.range(at: 2), in: pattern) { + numberPattern = String(pattern[range]) + } + } else { + numberPattern = pattern + } + } else { + numberPattern = nil + } } } @@ -35,11 +54,12 @@ extension OpenHABStateDescription { let step: Double? let readOnly: Bool? let options: [OpenHABOptions]? + let pattern: String? } } extension OpenHABStateDescription.CodingData { var openHABStateDescription: OpenHABStateDescription { - OpenHABStateDescription(minimum: minimum, maximum: maximum, step: step, readOnly: readOnly, options: options) + OpenHABStateDescription(minimum: minimum, maximum: maximum, step: step, readOnly: readOnly, options: options, pattern: pattern) } } diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index e2ee3fb55..65fab9628 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -49,6 +49,56 @@ protocol Widget: AnyObject { func flatten(_: [ChildWidget]) } +extension String { + func parseAsBool() -> Bool { + if self == "ON" { return true } + if let brightness = parseAsBrightness() { return brightness != 0 } + if let decimalValue = Int(self) { + return decimalValue > 0 + } else { + return false + } + } + + func parseAsNumber(format: String? = nil) -> NumberState { + switch self { + case "ON": return NumberState(value: 100.0) + case "OFF": return NumberState(value: 0.0) + default: + let components = split(separator: " ").map { String($0) } + let number = String(components[safe: 0] ?? "") + let unit = components[safe: 1] + return NumberState(value: number.stateAsDouble(), unit: unit, format: format) + } + } + + func parseAsUIColor() -> UIColor { + if self == "Uninitialized" { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } else { + let values = components(separatedBy: ",") + if values.count == 3 { + let hue = CGFloat(state: values[0], divisor: 360) + let saturation = CGFloat(state: values[1], divisor: 100) + let brightness = CGFloat(state: values[2], divisor: 100) + os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) + return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) + } else { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } + } + } + + func parseAsBrightness() -> Int? { + let values = components(separatedBy: ",") + if values.count == 3 { + return Int(values[2].stateAsDouble().rounded()) + } else { + return nil + } + } +} + public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var id: String = "" @@ -56,14 +106,14 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var widgetId = "" public var label = "" public var icon = "" - public var type = "" + public var type: WidgetType? public var url = "" public var period = "" public var minValue = 0.0 public var maxValue = 100.0 public var step = 1.0 public var refresh = 0 - public var height = "" + public var height: Double? public var isLeaf = false public var iconColor = "" public var labelcolor = "" @@ -78,6 +128,8 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var mappings: [OpenHABWidgetMapping] = [] public var image: UIImage? public var widgets: [OpenHABWidget] = [] + public var visibility = true + public var switchSupport = false // Text prior to "[" public var labelText: String? { @@ -106,6 +158,36 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { } } + public var stateValueAsBool: Bool? { + item?.state?.parseAsBool() + } + + public var stateValueAsBrightness: Int? { + item?.state?.parseAsBrightness() + } + + public var stateValueAsUIColor: UIColor? { + item?.state?.parseAsUIColor() + } + + public var stateValueAsNumberState: NumberState? { + item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) + } + + public func sendItemUpdate(state: NumberState?) { + guard let item = item, let state = state else { + os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) + return + } + if item.isOfTypeOrGroupType(.numberWithDimension) { + // For number items, include unit (if present) in command + sendCommand(state.toString(locale: Locale(identifier: "US"))) + } else { + // For all other items, send the plain value + sendCommand(state.formatValue()) + } + } + public func sendCommandDouble(_ command: Double) { sendCommand(String(command)) } @@ -129,16 +211,12 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { 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 { - guard let double = with else { return "" } - return String(format: "%.1f", double) - } + 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], visibility: Bool?, switchSupport: Bool?) { self.init() id = widgetId self.widgetId = widgetId self.label = label - self.type = type + self.type = type.toWidgetType() self.icon = icon self.url = url ?? "" self.period = period ?? "" @@ -151,7 +229,7 @@ extension OpenHABWidget { } else { self.refresh = 0 } - self.height = toString(height) + self.height = height self.isLeaf = isLeaf ?? false self.iconColor = iconColor ?? "" labelcolor = labelColor ?? "" @@ -169,6 +247,8 @@ extension OpenHABWidget { // Sanitize minValue, maxValue and step: min <= max, step >= 0 self.maxValue = max(self.minValue, self.maxValue) self.step = abs(self.step) + self.visibility = visibility ?? true + self.switchSupport = switchSupport ?? false } convenience init(xml xmlElement: XMLElement) { @@ -179,7 +259,7 @@ extension OpenHABWidget { switch child.tag { case "widgetId": widgetId = child.stringValue case "label": label = child.stringValue - case "type": type = child.stringValue + case "type": type = child.stringValue.toWidgetType() case "icon": icon = child.stringValue case "url": url = child.stringValue case "period": period = child.stringValue @@ -189,7 +269,7 @@ extension OpenHABWidget { case "service": service = child.stringValue case "state": state = child.stringValue case "text": text = child.stringValue - case "height": height = child.stringValue + case "height": height = Double(child.stringValue) case "encoding": encoding = child.stringValue // Double case "minValue": minValue = Double(child.stringValue) ?? 0.0 @@ -239,6 +319,8 @@ extension OpenHABWidget { let linkedPage: OpenHABLinkedPage? let mappings: [OpenHABWidgetMapping] let widgets: [OpenHABWidget.CodingData] + let visibility: Bool? + let switchSupport: Bool? } } @@ -246,7 +328,7 @@ extension OpenHABWidget { extension OpenHABWidget.CodingData { var openHABWidget: OpenHABWidget { 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) + 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, visibility: visibility, switchSupport: switchSupport) } } diff --git a/openHABCore/Sources/Util/DoubleExtension.swift b/openHABCore/Sources/Util/DoubleExtension.swift index 7c8beeac6..668b9a403 100644 --- a/openHABCore/Sources/Util/DoubleExtension.swift +++ b/openHABCore/Sources/Util/DoubleExtension.swift @@ -16,6 +16,7 @@ extension Double { let digits = max(-Decimal(step).exponent, 0) let numberFormatter = NumberFormatter() numberFormatter.maximumFractionDigits = digits + numberFormatter.minimumFractionDigits = digits numberFormatter.decimalSeparator = "." return numberFormatter.string(from: NSNumber(value: self)) ?? "" } diff --git a/openHABCore/Sources/Util/Endpoint.swift b/openHABCore/Sources/Util/Endpoint.swift index 25f5a913a..f01c1513c 100644 --- a/openHABCore/Sources/Util/Endpoint.swift +++ b/openHABCore/Sources/Util/Endpoint.swift @@ -73,14 +73,14 @@ extension Endpoint { } // swiftlint:disable:next function_parameter_count - public static func chart(rootUrl: String, period: String?, type: String?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> Endpoint { + public static func chart(rootUrl: String, period: String?, type: ItemType?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> 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") { + if type == .group { endpoint.queryItems.append(URLQueryItem(name: "groups", value: name)) } else { endpoint.queryItems.append(URLQueryItem(name: "items", value: name)) diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 9a7a80767..59413c03f 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -11,6 +11,40 @@ import Foundation +public enum ItemType { + case color + case contact + case dateTime + case dimmer + case group + case image + case location + case number + case numberWithDimension + case player + case rollershutter + case stringItem + case switchItem +} + +public enum WidgetType { + case chart + case colorpicker + case defaultWidget + case frame + case group + case image + case mapview + case selection + case setpoint + case slider + case switchWidget + case text + case video + case webview + case unknown +} + extension String { var doubleValue: Double { let formatter = NumberFormatter() @@ -41,4 +75,57 @@ extension String { formatter.decimalSeparator = "." return formatter.number(from: filter("01234567890.-".contains)) } + + func toItemType() -> ItemType? { + var typeString: String = self + // Earlier OH2 versions returned e.g. 'Switch' as 'SwitchItem' + if hasSuffix("Item") { + typeString = String(dropLast(4)) + } + // types can have subtypes (e.g. 'Number:Temperature'); split off those + let firstColon = firstIndex(of: ":") + if let firstColon = firstColon { + typeString = String(typeString[.. WidgetType? { + switch self { + case "Chart": return .chart + case "Colorpicker": return .colorpicker + case "Default": return .defaultWidget + case "Frame": return .frame + case "Group": return .group + case "Image": return .image + case "Mapview": return .mapview + case "Selection": return .selection + case "Setpoint": return .setpoint + case "Slider": return .slider + case "Switch": return .switchWidget + case "Text": return .text + case "Video": return .video + case "Webview": return .webview + case "Unknown": return .unknown + default: return .unknown + } + } } diff --git a/openHABTestsSwift/NumberStateTest.swift b/openHABTestsSwift/NumberStateTest.swift new file mode 100644 index 000000000..ced482b06 --- /dev/null +++ b/openHABTestsSwift/NumberStateTest.swift @@ -0,0 +1,65 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import XCTest + +@testable import openHAB +@testable import OpenHABCore + +class NumberStateTest: XCTestCase { + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testNumberState() throws { + XCTAssertEqual(NumberState(value: 100.3, format: "%d").toString(locale: nil), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%d").toString(locale: Locale(identifier: "US")), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%d").toString(locale: Locale(identifier: "US")), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%.1f").toString(locale: Locale(identifier: "US")), "100.4") + XCTAssertEqual(NumberState(value: 100.4, format: "%.1f").toString(locale: Locale(identifier: "de")), "100,4") + XCTAssertEqual(NumberState(value: 100.4, unit: "K", format: "%.1f %unit%").toString(locale: Locale(identifier: "US")), "100.4 K") + XCTAssertEqual(NumberState(value: 100.4, unit: "", format: "%.1f %unit%").toString(locale: Locale(identifier: "US")), "100.4 ") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: nil).toString(locale: Locale(identifier: "US")), "100.4 °C") + XCTAssertEqual(NumberState(value: 100.4, unit: nil, format: nil).toString(locale: Locale(identifier: "US")), "100.4") + } + + func testToItemType() throws { + XCTAssertEqual("NumberItem".toItemType(), ItemType.number) + XCTAssertEqual("Number:Temperature".toItemType(), ItemType.numberWithDimension) + XCTAssertEqual("String".toItemType(), ItemType.stringItem) + XCTAssertEqual("blabla".toItemType(), nil) + } + + func testToWidgetType() throws { + XCTAssertEqual("Colorpicker".toWidgetType(), WidgetType.colorpicker) + XCTAssertEqual("colorpicker".toWidgetType(), WidgetType.unknown) + } + + func testParseAs() throws { + XCTAssertEqual("ON".parseAsBool(), true) + XCTAssertEqual("4,3,1".parseAsBrightness(), 1) + XCTAssertEqual("4,31".parseAsBrightness(), nil) + XCTAssertEqual("4,3,0".parseAsBool(), false) + XCTAssertEqual("4,3,1".parseAsBool(), true) + XCTAssertEqual("1".parseAsBool(), true) + XCTAssertEqual("0".parseAsBool(), false) + XCTAssertEqual("ON".parseAsNumber(), NumberState(value: 100.0)) + XCTAssertEqual("OFF".parseAsNumber(), NumberState(value: 0.0)) + XCTAssertEqual("24.4 °F".parseAsNumber(), NumberState(value: 24.4, unit: "°F", format: nil)) + XCTAssertEqual("24.4 °F".parseAsNumber(format: "%.f"), NumberState(value: 24.4, unit: "°F", format: "%.f")) + XCTAssertEqual("Uninitialized".parseAsUIColor(), UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0)) + XCTAssertEqual("360,100,100".parseAsUIColor(), UIColor(hue: CGFloat(state: "360", divisor: 360), saturation: CGFloat(state: "100", divisor: 100), brightness: CGFloat(state: "100", divisor: 100), alpha: 1.0)) + } +} diff --git a/openHABTestsSwift/OpenHABXMLParserTests.swift b/openHABTestsSwift/OpenHABXMLParserTests.swift index 74c63fa9e..91fc1fb23 100644 --- a/openHABTestsSwift/OpenHABXMLParserTests.swift +++ b/openHABTestsSwift/OpenHABXMLParserTests.swift @@ -27,9 +27,6 @@ class OpenHABXMLParserTests: XCTestCase { } func testFuziParser() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - let xml = """ NumberItem @@ -43,7 +40,7 @@ class OpenHABXMLParserTests: XCTestCase { let document = try XMLDocument(data: xml) if let root = document.root { let item = OpenHABItem(xml: root) - XCTAssertEqual(item.type, "NumberItem") + XCTAssertEqual(item.type, .number) } else { throw TestingError.noXMLDocument } diff --git a/openHABTestsSwift/restAPI.json b/openHABTestsSwift/restAPI.json new file mode 100644 index 000000000..d122a4c74 --- /dev/null +++ b/openHABTestsSwift/restAPI.json @@ -0,0 +1,31 @@ +{"name":"testUoM", + "label":"testUoM", + "link":"http://192.168.2.15:8081/rest/sitemaps/testUoM", + "homepage":{ + "id":"testing", + "title":"testUoM","link":"http://192.168.2.15:8081/rest/sitemaps/testing/testing","leaf":false,"timeout":false, + "widgets": + [{"widgetId":"00", + "type":"Frame", + "visibility":true, + "label":"Statistik", + "icon":"frame", + "mappings":[], + "widgets": + [{"widgetId":"0000", + "type":"Setpoint", + "visibility":true, + "label":"Time in minutes for sitemap [40.0 min]", + "icon":"number", + "mappings":[], + "minValue":5, + "maxValue":60, + "step":5, + "item":{"link":"http://192.168.2.15:8081/rest/items/iSomeUoMItem", + "state":"40 min", + "stateDescription":{ + "pattern":"%,.1f s", + "readOnly":false, + "options":[]}, + "type":"Number:Time", + "name":"iSomeUoMItem","label":"Time in seconds from/to actor DPT 7.005","tags":[],"groupNames":[]},"widgets":[]}]}]}} diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index a7c20648f..c8bef6897 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -74,7 +74,7 @@ struct ContentView: View { return AnyView(ImageRow(URL: URL(string: widget.url))) } case .chart: - let url = Endpoint.chart(rootUrl: settings.openHABRootUrl, period: widget.period, type: widget.item?.type, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: .dark).url + let url = Endpoint.chart(rootUrl: settings.openHABRootUrl, period: widget.period, type: widget.item?.type ?? .none, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: .dark).url return AnyView(ImageRow(URL: url)) case .mapview: return AnyView(MapViewRow(widget: widget)) diff --git a/openHABWatch Extension/Views/Rows/ImageRawRow.swift b/openHABWatch Extension/Views/Rows/ImageRawRow.swift index 01fe0126b..44e0c0d93 100644 --- a/openHABWatch Extension/Views/Rows/ImageRawRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRawRow.swift @@ -21,7 +21,7 @@ struct ImageRawRow: View { var body: some View { var imageView: some View { - if let data = widget.item?.state.components(separatedBy: ",")[safe: 1], + if let data = widget.item?.state?.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters), let image = UIImage(data: decodedData) { return AnyView(Image(uiImage: image) diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 3544f6bb4..2ef1c6c59 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -19,7 +19,7 @@ import MapKit import OpenHABCoreWatch import os.log -enum StateEnum { +enum WidgetTypeEnum { case switcher(Bool) case slider(Double) case segmented(Int) @@ -72,7 +72,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO var image: UIImage? var widgets: [ObservableOpenHABWidget] = [] - @Published var stateEnumBinding: StateEnum = .unassigned + @Published var stateEnumBinding: WidgetTypeEnum = .unassigned // Text prior to "[" var labelText: String? { @@ -109,7 +109,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } - var stateEnum: StateEnum { + var stateEnum: WidgetTypeEnum { switch type { case "Frame": return .frame @@ -117,10 +117,9 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 if !mappings.isEmpty { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) - // RollershutterItem changed to Rollershutter in later builds of OH2 - } else if let type = item?.type, type == "Switch" { + } else if let type = item?.type, type == .switchItem { return .switcher(item?.state == "ON" ? true : false) - } else if let type = item?.type, type.isAny(of: "RollershutterItem", "Rollershutter") || (type == "Group" && item?.groupType == "Rollershutter") { + } else if let type = item?.type, type == .rollershutter || (type == .group && item?.groupType == .rollershutter) { return .rollershutter } else if item?.stateDescription?.options.count ?? 0 > 0 { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) From 7d5fd074a5cf33b3976b2646f964b6b888815d82 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sat, 1 Aug 2020 17:06:08 +0200 Subject: [PATCH 04/78] Update openHAB/SetpointUITableViewCell.swift Co-authored-by: weakfl --- openHAB/SetpointUITableViewCell.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openHAB/SetpointUITableViewCell.swift b/openHAB/SetpointUITableViewCell.swift index 82bf0126b..341790a5e 100644 --- a/openHAB/SetpointUITableViewCell.swift +++ b/openHAB/SetpointUITableViewCell.swift @@ -47,8 +47,10 @@ class SetpointUITableViewCell: GenericUITableViewCell { let stateValue = numberState?.value ?? widget.minValue let newValue: Double switch down { - case true: newValue = stateValue - widget.step - case false: newValue = stateValue + widget.step + case true: + newValue = stateValue - widget.step + case false: + newValue = stateValue + widget.step } if newValue >= widget.minValue, newValue <= widget.maxValue { numberState?.value = newValue From 31508f917fd0693720f783852bb7f6bb19d7a585 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sat, 1 Aug 2020 17:24:33 +0200 Subject: [PATCH 05/78] Update openHABCore/Sources/Util/StringExtension.swift Co-authored-by: weakfl --- .../Sources/Util/StringExtension.swift | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 59413c03f..80322dde9 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -11,38 +11,38 @@ import Foundation -public enum ItemType { - case color - case contact - case dateTime - case dimmer - case group - case image - case location - case number - case numberWithDimension - case player - case rollershutter - case stringItem - case switchItem +public enum ItemType: String { + case color = "Color" + case contact = "Contact" + case dateTime = "DateTime" + case dimmer = "Dimmer" + case group = "Group" + case image = "Image" + case location = "Location" + case number = "Number" + case numberWithDimension = "NumberWithDimension" + case player = "Player" + case rollershutter = "Rollershutter" + case stringItem = "String" + case switchItem = "Switch" } -public enum WidgetType { - case chart - case colorpicker - case defaultWidget - case frame - case group - case image - case mapview - case selection - case setpoint - case slider - case switchWidget - case text - case video - case webview - case unknown +public enum WidgetType: String { + case chart = "Chart" + case colorpicker = "Colorpicker" + case defaultWidget = "Default" + case frame = "Frame" + case group = "Group" + case image = "Image" + case mapview = "Mapview" + case selection = "Selection" + case setpoint = "Setpoint" + case slider = "Slider" + case switchWidget = "Switch" + case text = "Text" + case video = "Video" + case webview = "Webview" + case unknown = "Unknown" } extension String { From 9a4c7a2020a9ba3a70c062ee4120ce1ef1f48816 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sat, 1 Aug 2020 17:26:36 +0200 Subject: [PATCH 06/78] Update openHABCore/Sources/Util/StringExtension.swift Co-authored-by: weakfl --- .../Sources/Util/StringExtension.swift | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 80322dde9..5be3dbed3 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -91,41 +91,11 @@ extension String { if typeString == "Number", firstColon != nil { return .numberWithDimension } - switch typeString { - case "Color": return .color - case "Contact": return .contact - case "DateTime": return .dateTime - case "Dimmer": return .dimmer - case "Group": return .group - case "Image": return .image - case "Location": return .location - case "Number": return .number - case "Player": return .player - case "Rollershutter": return .rollershutter - case "Switch": return .switchItem - case "String": return .stringItem - default: return nil - } + + return ItemType(rawValue: typeString) } func toWidgetType() -> WidgetType? { - switch self { - case "Chart": return .chart - case "Colorpicker": return .colorpicker - case "Default": return .defaultWidget - case "Frame": return .frame - case "Group": return .group - case "Image": return .image - case "Mapview": return .mapview - case "Selection": return .selection - case "Setpoint": return .setpoint - case "Slider": return .slider - case "Switch": return .switchWidget - case "Text": return .text - case "Video": return .video - case "Webview": return .webview - case "Unknown": return .unknown - default: return .unknown - } + WidgetType(rawValue: self) } } From b052a0b581c8cf00c1f0d2348c56d9583b357a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sat, 1 Aug 2020 17:30:13 +0200 Subject: [PATCH 07/78] Removed commented code in OpenHABViewController.swift Encapsulated unit, format to private(set) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/OpenHABViewController.swift | 4 ---- openHABCore/Sources/Model/NumberState.swift | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index fef2bf0ba..62a6bf0af 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1061,10 +1061,6 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { placeholder: UIImage(named: "blankicon.png"), options: [.processor(SVGProcessor())], completionHandler: reportOnResults) -// cell.imageView?.kf.setImage(with: ImageResource(downloadURL: urlc, cacheKey: urlc.path + (urlc.query ?? "")), -// placeholder: UIImage(named: "blankicon.png"), -// options: [.processor(SVGPocketProcessor(size: cell.imageView?.frame.size ?? CGSize(width: 10, height: 10)))], -// completionHandler: reportOnResults) } } } diff --git a/openHABCore/Sources/Model/NumberState.swift b/openHABCore/Sources/Model/NumberState.swift index 57cc32ad9..825a75dd1 100644 --- a/openHABCore/Sources/Model/NumberState.swift +++ b/openHABCore/Sources/Model/NumberState.swift @@ -17,8 +17,8 @@ public struct NumberState: CustomStringConvertible, Equatable { } public var value: Double - var unit: String? = "" - var format: String? = "" + private(set) var unit: String? = "" + private(set) var format: String? = "" func toString(locale: Locale?) -> String { if let format = format, format.isEmpty == false { From 5c2426384d3d3a4c84bf75a77b583f9bb4bbd712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sat, 1 Aug 2020 18:49:41 +0200 Subject: [PATCH 08/78] Upgrading cocoapod to suppress more warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- .swiftformat | 3 +- Podfile.lock | 130 ++++++------- openHAB/OpenHABViewController.swift | 180 +++++++++--------- openHAB/ScaleAspectFitImageView.swift | 10 +- openHABCore/Sources/Model/OpenHABItem.swift | 20 +- .../Sources/Model/OpenHABSitemapPage.swift | 2 +- openHABCore/Sources/Model/OpenHABWidget.swift | 52 +---- openHABCore/Sources/Util/Preferences.swift | 24 +-- .../Sources/Util/StringExtension.swift | 50 +++++ .../Views/ContentView.swift | 6 +- .../Views/Rows/GenericRow.swift | 2 +- .../Views/Rows/SegmentRow.swift | 2 +- .../Views/Rows/SetpointRow.swift | 2 +- .../Views/Rows/SliderRow.swift | 2 +- .../Views/Rows/SwitchRow.swift | 2 +- .../Model/ObservableOpenHABSitemapPage.swift | 2 +- .../Model/ObservableOpenHABWidget.swift | 2 +- .../openHABWatch Extension/UserData.swift | 84 ++++---- .../external/AppMessageService.swift | 2 +- 19 files changed, 287 insertions(+), 290 deletions(-) diff --git a/.swiftformat b/.swiftformat index e3bb8df7b..7045766d2 100644 --- a/.swiftformat +++ b/.swiftformat @@ -1,11 +1,12 @@ # file options ---swiftversion 5.1 +--swiftversion 5.2 --exclude Pods --symlinks ignore # disabled rules --disable specifiers # see https://github.com/nicklockwood/SwiftFormat/issues/364 --disable redundantParens +--disable wrapMultilineStatementBraces # opt-in rules --enable isEmpty diff --git a/Podfile.lock b/Podfile.lock index a65599b3f..3f0585e02 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,78 +1,76 @@ PODS: - Alamofire (4.9.1) - - CocoaLumberjack (3.6.1): - - CocoaLumberjack/Core (= 3.6.1) - - CocoaLumberjack/Core (3.6.1) + - CocoaLumberjack (3.6.2): + - CocoaLumberjack/Core (= 3.6.2) + - CocoaLumberjack/Core (3.6.2) - Crashlytics (3.14.0): - Fabric (~> 1.10.2) - DeviceKit (3.2.0) - DynamicButton (6.2.1) - Fabric (1.10.2) - - Firebase/Analytics (6.27.0): + - Firebase/Analytics (6.29.0): - Firebase/Core - - Firebase/Core (6.27.0): + - Firebase/Core (6.29.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.6.1) - - Firebase/CoreOnly (6.27.0): - - FirebaseCore (= 6.8.0) - - FirebaseAnalytics (6.6.1): + - FirebaseAnalytics (= 6.7.0) + - Firebase/CoreOnly (6.29.0): + - FirebaseCore (= 6.9.2) + - FirebaseAnalytics (6.7.0): - FirebaseCore (~> 6.8) - FirebaseInstallations (~> 1.4) - - GoogleAppMeasurement (= 6.6.1) - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" + - GoogleAppMeasurement (= 6.7.0) + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" - nanopb (~> 1.30905.0) - - FirebaseCore (6.8.0): + - FirebaseCore (6.9.2): - FirebaseCoreDiagnostics (~> 1.3) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) - - FirebaseCoreDiagnostics (1.4.0): - - GoogleDataTransportCCTSupport (~> 3.1) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) + - FirebaseCoreDiagnostics (1.5.0): + - GoogleDataTransport (~> 7.0) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) - nanopb (~> 1.30905.0) - - FirebaseInstallations (1.4.0): + - FirebaseInstallations (1.5.0): - FirebaseCore (~> 6.8) - - GoogleUtilities/Environment (~> 6.6) - - GoogleUtilities/UserDefaults (~> 6.6) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/UserDefaults (~> 6.7) - PromisesObjC (~> 1.2) - FlexColorPicker (1.4.2) - Fuzi (3.1.2) - - GoogleAppMeasurement (6.6.1): - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" + - GoogleAppMeasurement (6.7.0): + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" - nanopb (~> 1.30905.0) - - GoogleDataTransport (6.2.1) - - GoogleDataTransportCCTSupport (3.2.0): - - GoogleDataTransport (~> 6.1) + - GoogleDataTransport (7.1.0): - nanopb (~> 1.30905.0) - - GoogleUtilities/AppDelegateSwizzler (6.6.0): + - GoogleUtilities/AppDelegateSwizzler (6.7.1): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.6.0): + - GoogleUtilities/Environment (6.7.1): - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.6.0): + - GoogleUtilities/Logger (6.7.1): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.6.0): + - GoogleUtilities/MethodSwizzler (6.7.1): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.6.0): + - GoogleUtilities/Network (6.7.1): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.6.0)" - - GoogleUtilities/Reachability (6.6.0): + - "GoogleUtilities/NSData+zlib (6.7.1)" + - GoogleUtilities/Reachability (6.7.1): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.6.0): + - GoogleUtilities/UserDefaults (6.7.1): - GoogleUtilities/Logger - - Kingfisher (5.14.0): - - Kingfisher/Core (= 5.14.0) - - Kingfisher/Core (5.14.0) - - Kingfisher/SwiftUI (5.14.0): + - Kingfisher (5.14.1): + - Kingfisher/Core (= 5.14.1) + - Kingfisher/Core (5.14.1) + - Kingfisher/SwiftUI (5.14.1): - Kingfisher/Core - nanopb (1.30905.0): - nanopb/decode (= 1.30905.0) @@ -80,14 +78,14 @@ PODS: - nanopb/decode (1.30905.0) - nanopb/encode (1.30905.0) - PromisesObjC (1.2.9) - - SideMenu (6.4.8) + - SideMenu (6.4.9) - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.44.14) + - SwiftFormat/CLI (0.45.2) - SwiftLint (0.39.2) - - SwiftMessages (7.0.1): - - SwiftMessages/App (= 7.0.1) - - SwiftMessages/App (7.0.1) + - SwiftMessages (8.0.0): + - SwiftMessages/App (= 8.0.0) + - SwiftMessages/App (8.0.0) DEPENDENCIES: - Alamofire (~> 4.0) @@ -123,7 +121,6 @@ SPEC REPOS: - Fuzi - GoogleAppMeasurement - GoogleDataTransport - - GoogleDataTransportCCTSupport - GoogleUtilities - Kingfisher - nanopb @@ -140,36 +137,35 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: SVGKit: - :commit: 2a4068f0ea546dcd82f7e4dd9aa9026c0a0a2235 + :commit: 9240977515c04053f8c96c9dfdb764dc7b98b9ba :git: https://github.com/SVGKit/SVGKit.git SPEC CHECKSUMS: Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 - CocoaLumberjack: b17ae15142558d08bbacf69775fa10c4abbebcc9 + CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94 Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df DeviceKit: d081659419cce07c0b5239dbc9fb39ed7413c7fe DynamicButton: 95f30460793bd3510a5c213ac1b810a5e3d54b6a Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 - Firebase: fc4cbf6f1592636431821ef9a3c557e4dfd9f268 - FirebaseAnalytics: 0ea640473474f036cabbc2576e20c2d63671c92f - FirebaseCore: feda061cb1ee6d8ad4824f4a4a8ffbcfe284f595 - FirebaseCoreDiagnostics: 4505e4d4009b1d93f605088ee7d7764d5f0d1c84 - FirebaseInstallations: 293f567159b6d66d1c990f13bb868066096c94ec + Firebase: 57957c8d6eb3d8b80a560b1dc58be24724b89ff2 + FirebaseAnalytics: aa522dce9fd93002ba1554467d23ce7092323000 + FirebaseCore: 7930a1946517d94256d857f97371ed993b55f7bd + FirebaseCoreDiagnostics: 7535fe695737f8c5b350584292a70b7f8ff0357b + FirebaseInstallations: 3c520c951305cbf9ca54eb891ff9e6d1fd384881 FlexColorPicker: d7ed5cfd8ceb936f2930e4e30629f9448967a5f8 Fuzi: dba7215e52fb39dd7b1a62f69ede1e30edff0ae1 - GoogleAppMeasurement: 2fd5c5a56c069db635c8e7b92d4809a9591d0a69 - GoogleDataTransport: 9a8a16f79feffc7f42096743de2a7c4815e84020 - GoogleDataTransportCCTSupport: 489c1265d2c85b68187a83a911913d190012158d - GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 - Kingfisher: 7b64389a43139c903ec434788344c288217c792d + GoogleAppMeasurement: 345d365fd105e6682bf5084783a5352a3db26820 + GoogleDataTransport: af0c79193dc59acd37630b4833d0dc6912ae6bd5 + GoogleUtilities: e121a3867449ce16b0e35ddf1797ea7a389ffdf2 + Kingfisher: 8050bc6f7f68cbf3908bd04df7ccbac188f6d6d6 nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 - SideMenu: 4a891be552d30bb6fa87ad404d62e485f8450c34 - SVGKit: c6fe3403caafbd20d4ad5a5cc7dcae6115b3c6e1 - SwiftFormat: a5ab293a7f6a812bec6f4ffc5507b7ed08f7f6e1 + SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 + SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63 + SwiftFormat: 07a1794c1331daaefc1ca6c2ff1da38ee9ca090a SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 - SwiftMessages: b577dc7043be8b299857ab35bb663dbff6483bd0 + SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 -PODFILE CHECKSUM: c2a5a545af2eb4e0cc66d2ee9aa3b6a5dc5c4512 +PODFILE CHECKSUM: 7e3ab1cfad25c0c0ad6f55cd58134ce3b910ec2e COCOAPODS: 1.9.3 diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 62a6bf0af..5bac2d6ff 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -418,106 +418,106 @@ class OpenHABViewController: UIViewController { currentPageOperation = NetworkConnection.page(pageUrl: pageUrl, longPolling: longPolling, openHABVersion: appData?.openHABVersion ?? 2) { [weak self] response in - guard let self = self else { return } + guard let self = self else { return } - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - let headers = response.response?.allHeaderFields + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + let headers = response.response?.allHeaderFields - NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" - if !NetworkConnection.atmosphereTrackingId.isEmpty { - os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) - } - var openHABSitemapPage: OpenHABSitemapPage? - if let data = response.result.value { - // If we are talking to openHAB 1.X, talk XML - if self.appData?.openHABVersion == 1 { - let str = String(decoding: data, as: UTF8.self) - os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) - - guard let doc = try? XMLDocument(data: data) else { return } - if let rootElement = doc.root, let name = rootElement.tag { - os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) - if name == "page" { - openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" + if !NetworkConnection.atmosphereTrackingId.isEmpty { + os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) + } + var openHABSitemapPage: OpenHABSitemapPage? + if let data = response.result.value { + // If we are talking to openHAB 1.X, talk XML + if self.appData?.openHABVersion == 1 { + let str = String(decoding: data, as: UTF8.self) + os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + + guard let doc = try? XMLDocument(data: data) else { return } + if let rootElement = doc.root, let name = rootElement.tag { + os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) + if name == "page" { + openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + } + } + } else { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } - } - } else { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } } - } - self.currentPage = openHABSitemapPage - if self.isFiltering { - self.filterContentForSearchText(self.search.searchBar.text) - } - - self.currentPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - self.widgetTableView.reloadData() - UIApplication.shared.isNetworkActivityIndicatorVisible = false - self.refreshControl?.endRefreshing() - self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] - self.loadPage(true) - 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) + self.currentPage = openHABSitemapPage + if self.isFiltering { + self.filterContentForSearchText(self.search.searchBar.text) + } - NetworkConnection.atmosphereTrackingId = "" - 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 { - os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) - } else { - // Error - DispatchQueue.main.async { - if (error as NSError?)?.code == -1012 { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: "Error", body: "SSL Certificate Error") - view.button?.setTitle("Dismiss", for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view - } - } else { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: "Error", body: error.localizedDescription) - view.button?.setTitle("Dismiss", for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view + self.currentPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } + self.widgetTableView.reloadData() + UIApplication.shared.isNetworkActivityIndicatorVisible = false + self.refreshControl?.endRefreshing() + self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] + self.loadPage(true) + 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 { + os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) + self.loadPage(false) + } else if (error as NSError?)?.code == -999 { + os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) + } else { + // Error + DispatchQueue.main.async { + if (error as NSError?)?.code == -1012 { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: "Error", body: "SSL Certificate Error") + view.button?.setTitle("Dismiss", for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } + } else { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: "Error", body: error.localizedDescription) + view.button?.setTitle("Dismiss", for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } } } } } - } } currentPageOperation?.resume() diff --git a/openHAB/ScaleAspectFitImageView.swift b/openHAB/ScaleAspectFitImageView.swift index 06aa7e714..091727d6f 100644 --- a/openHAB/ScaleAspectFitImageView.swift +++ b/openHAB/ScaleAspectFitImageView.swift @@ -15,26 +15,26 @@ public class ScaleAspectFitImageView: UIImageView { private var aspectRatioConstraint: NSLayoutConstraint? override public var image: UIImage? { didSet { - self.updateAspectRatioConstraint() + updateAspectRatioConstraint() } } - required public init?(coder aDecoder: NSCoder) { + public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - public override init(frame: CGRect) { + override public init(frame: CGRect) { super.init(frame: frame) setup() } - public override init(image: UIImage!) { + override public init(image: UIImage!) { super.init(image: image) setup() } - public override init(image: UIImage!, highlightedImage: UIImage?) { + override public init(image: UIImage!, highlightedImage: UIImage?) { super.init(image: image, highlightedImage: highlightedImage) setup() } diff --git a/openHABCore/Sources/Model/OpenHABItem.swift b/openHABCore/Sources/Model/OpenHABItem.swift index cbe2f0ea5..e7c8e2a73 100644 --- a/openHABCore/Sources/Model/OpenHABItem.swift +++ b/openHABCore/Sources/Model/OpenHABItem.swift @@ -25,6 +25,15 @@ public final class OpenHABItem: NSObject, CommItem { public var members: [OpenHABItem] = [] public var category = "" + var canBeToggled: Bool { + isOfTypeOrGroupType(ItemType.color) || + isOfTypeOrGroupType(ItemType.contact) || + isOfTypeOrGroupType(ItemType.dimmer) || + isOfTypeOrGroupType(ItemType.rollershutter) || + isOfTypeOrGroupType(ItemType.switchItem) || + isOfTypeOrGroupType(ItemType.player) + } + public init(name: String, type: String, state: String?, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?, members: [OpenHABItem], category: String?) { self.name = name self.type = type.toItemType() @@ -60,15 +69,6 @@ public final class OpenHABItem: NSObject, CommItem { func isOfTypeOrGroupType(_ type: ItemType) -> Bool { self.type == type || groupType == type } - - var canBeToggled: Bool { - isOfTypeOrGroupType(ItemType.color) || - isOfTypeOrGroupType(ItemType.contact) || - isOfTypeOrGroupType(ItemType.dimmer) || - isOfTypeOrGroupType(ItemType.rollershutter) || - isOfTypeOrGroupType(ItemType.switchItem) || - isOfTypeOrGroupType(ItemType.player) - } } extension String { @@ -167,7 +167,7 @@ extension OpenHABItem { extension OpenHABItem.CodingData { public var openHABItem: OpenHABItem { - let mappedMembers = members?.map { $0.openHABItem } ?? [] + let mappedMembers = members?.map(\.openHABItem) ?? [] return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, members: mappedMembers, category: category) } diff --git a/openHABCore/Sources/Model/OpenHABSitemapPage.swift b/openHABCore/Sources/Model/OpenHABSitemapPage.swift index 1f136a59a..1c967fe3e 100644 --- a/openHABCore/Sources/Model/OpenHABSitemapPage.swift +++ b/openHABCore/Sources/Model/OpenHABSitemapPage.swift @@ -112,7 +112,7 @@ extension OpenHABSitemapPage { extension OpenHABSitemapPage.CodingData { public var openHABSitemapPage: OpenHABSitemapPage { - let mappedWidgets = widgets?.map { $0.openHABWidget } ?? [] + let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] return OpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) } } diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index 65fab9628..fa1b2425a 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -49,56 +49,6 @@ protocol Widget: AnyObject { func flatten(_: [ChildWidget]) } -extension String { - func parseAsBool() -> Bool { - if self == "ON" { return true } - if let brightness = parseAsBrightness() { return brightness != 0 } - if let decimalValue = Int(self) { - return decimalValue > 0 - } else { - return false - } - } - - func parseAsNumber(format: String? = nil) -> NumberState { - switch self { - case "ON": return NumberState(value: 100.0) - case "OFF": return NumberState(value: 0.0) - default: - let components = split(separator: " ").map { String($0) } - let number = String(components[safe: 0] ?? "") - let unit = components[safe: 1] - return NumberState(value: number.stateAsDouble(), unit: unit, format: format) - } - } - - func parseAsUIColor() -> UIColor { - if self == "Uninitialized" { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } else { - let values = components(separatedBy: ",") - if values.count == 3 { - let hue = CGFloat(state: values[0], divisor: 360) - let saturation = CGFloat(state: values[1], divisor: 100) - let brightness = CGFloat(state: values[2], divisor: 100) - os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) - return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) - } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } - } - } - - func parseAsBrightness() -> Int? { - let values = components(separatedBy: ",") - if values.count == 3 { - return Int(values[2].stateAsDouble().rounded()) - } else { - return nil - } - } -} - public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var id: String = "" @@ -327,7 +277,7 @@ extension OpenHABWidget { // swiftlint:disable line_length extension OpenHABWidget.CodingData { var openHABWidget: OpenHABWidget { - let mappedWidgets = widgets.map { $0.openHABWidget } + let mappedWidgets = widgets.map(\.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, visibility: visibility, switchSupport: switchSupport) } } diff --git a/openHABCore/Sources/Util/Preferences.swift b/openHABCore/Sources/Util/Preferences.swift index 640d5d893..3bc15c3a4 100644 --- a/openHABCore/Sources/Util/Preferences.swift +++ b/openHABCore/Sources/Util/Preferences.swift @@ -77,22 +77,22 @@ public struct UserDefaultURL { } public struct Preferences { - static private let defaults = UserDefaults.standard + private static let defaults = UserDefaults.standard - @UserDefaultURL("localUrl", defaultValue: "") static public var localUrl: String - @UserDefaultURL("remoteUrl", defaultValue: "https://openhab.org:8444") static public var remoteUrl: String + @UserDefaultURL("localUrl", defaultValue: "") public static var localUrl: String + @UserDefaultURL("remoteUrl", defaultValue: "https://openhab.org:8444") public static var remoteUrl: String - @UserDefault("username", defaultValue: "test") static public var username: String - @UserDefault("password", defaultValue: "test") static public var password: String + @UserDefault("username", defaultValue: "test") public static var username: String + @UserDefault("password", defaultValue: "test") public static var password: String @UserDefault("alwaysSendCreds", defaultValue: false) public static var alwaysSendCreds: Bool - @UserDefault("ignoreSSL", defaultValue: false) static public var ignoreSSL: Bool + @UserDefault("ignoreSSL", defaultValue: false) public static var ignoreSSL: Bool // @UserDefault("sitemapName", defaultValue: "watch") static public var sitemapName: String - @UserDefault("demomode", defaultValue: true) static public var demomode: Bool - @UserDefault("idleOff", defaultValue: false) static public var idleOff: Bool - @UserDefault("realTimeSliders", defaultValue: false) static public var realTimeSliders: Bool - @UserDefault("iconType", defaultValue: 0) static public var iconType: Int - @UserDefault("defaultSitemap", defaultValue: "demo") static public var defaultSitemap: String - @UserDefault("sendCrashReports", defaultValue: false) static public var sendCrashReports: Bool + @UserDefault("demomode", defaultValue: true) public static var demomode: Bool + @UserDefault("idleOff", defaultValue: false) public static var idleOff: Bool + @UserDefault("realTimeSliders", defaultValue: false) public static var realTimeSliders: Bool + @UserDefault("iconType", defaultValue: 0) public static var iconType: Int + @UserDefault("defaultSitemap", defaultValue: "demo") public static var defaultSitemap: String + @UserDefault("sendCrashReports", defaultValue: false) public static var sendCrashReports: Bool static func readActiveUrl() -> String { if Preferences.remoteUrl != "" { diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 5be3dbed3..f08f071fc 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -10,6 +10,8 @@ // SPDX-License-Identifier: EPL-2.0 import Foundation +import MapKit +import os.log public enum ItemType: String { case color = "Color" @@ -98,4 +100,52 @@ extension String { func toWidgetType() -> WidgetType? { WidgetType(rawValue: self) } + + func parseAsBool() -> Bool { + if self == "ON" { return true } + if let brightness = parseAsBrightness() { return brightness != 0 } + if let decimalValue = Int(self) { + return decimalValue > 0 + } else { + return false + } + } + + func parseAsNumber(format: String? = nil) -> NumberState { + switch self { + case "ON": return NumberState(value: 100.0) + case "OFF": return NumberState(value: 0.0) + default: + let components = split(separator: " ").map { String($0) } + let number = String(components[safe: 0] ?? "") + let unit = components[safe: 1] + return NumberState(value: number.stateAsDouble(), unit: unit, format: format) + } + } + + func parseAsUIColor() -> UIColor { + if self == "Uninitialized" { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } else { + let values = components(separatedBy: ",") + if values.count == 3 { + let hue = CGFloat(state: values[0], divisor: 360) + let saturation = CGFloat(state: values[1], divisor: 100) + let brightness = CGFloat(state: values[2], divisor: 100) + os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) + return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) + } else { + return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + } + } + } + + func parseAsBrightness() -> Int? { + let values = components(separatedBy: ",") + if values.count == 3 { + return Int(values[2].stateAsDouble().rounded()) + } else { + return nil + } + } } diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index c8bef6897..d73c219cd 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -43,12 +43,12 @@ struct ContentView: View { buttons: [.default(Text("Abort")) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .deny }, - .default(Text("Once")) { + .default(Text("Once")) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitOnce }, - .default(Text("Always")) { + .default(Text("Always")) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitAlways - }]) + }]) } } diff --git a/openHABWatch Extension/Views/Rows/GenericRow.swift b/openHABWatch Extension/Views/Rows/GenericRow.swift index 7fb0cb0d5..a3305db8f 100644 --- a/openHABWatch Extension/Views/Rows/GenericRow.swift +++ b/openHABWatch Extension/Views/Rows/GenericRow.swift @@ -56,7 +56,7 @@ extension ObservableOpenHABWidget { // ContentView(viewModel: UserData(url: URL(string: pageUrl)), // settings: settings) ) { - Image(systemName: "chevron.right") + Image(systemName: "chevron.right") }) } else { diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index 750e46c0c..99a0a6cf9 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -24,7 +24,7 @@ struct SegmentRow: View { guard case let .segmented(value) = self.widget.stateEnumBinding else { return 0 } return value }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) // self.widget.sendCommand($0) self.widget.stateEnumBinding = .segmented($0) diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index 3e4792188..59b8f4a4f 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -37,7 +37,7 @@ struct SetpointRow: View { EncircledIconWithAction(systemName: "chevron.down.circle.fill", - action: self.decreaseValue) + action: self.decreaseValue) Spacer() diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index a2227f142..cf986d0c5 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -23,7 +23,7 @@ struct SliderRow: View { guard case let .slider(value) = self.widget.stateEnumBinding else { return 0 } return value }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) self.widget.sendCommand($0.valueText(step: self.widget.step)) self.widget.stateEnumBinding = .slider($0) diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index 64c592509..0ec3fb93f 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -24,7 +24,7 @@ struct SwitchRow: View { let stateBinding = Binding(get: { self.widget.stateEnumBinding.boolState }, - set: { + set: { if $0 { os_log("Switch to ON", log: .viewCycle, type: .info) self.widget.sendCommand("ON") diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift index 75b574537..6780a73e9 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift @@ -102,7 +102,7 @@ extension ObservableOpenHABSitemapPage { extension ObservableOpenHABSitemapPage.CodingData { var openHABSitemapPage: ObservableOpenHABSitemapPage { - let mappedWidgets = widgets?.map { $0.openHABWidget } ?? [] + let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] return ObservableOpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) } } diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 2ef1c6c59..92376ed93 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -297,7 +297,7 @@ extension ObservableOpenHABWidget { // swiftlint:disable line_length extension ObservableOpenHABWidget.CodingData { var openHABWidget: ObservableOpenHABWidget { - let mappedWidgets = widgets.map { $0.openHABWidget } + let mappedWidgets = widgets.map(\.openHABWidget) return ObservableOpenHABWidget(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) } } diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 28d3dd1a0..9cdb2d41a 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -125,17 +125,17 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: true, openHABVersion: 2) { [weak self] response in - guard self != nil else { return } + guard self != nil else { return } - switch response.result { - case .success: - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - promise.resolve(with: response.result.value ?? Data()) + switch response.result { + case .success: + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + promise.resolve(with: response.result.value ?? Data()) - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - promise.reject(with: error) - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + promise.reject(with: error) + } } currentPageOperation?.resume() @@ -167,44 +167,44 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: longPolling, openHABVersion: 2) { [weak self] response in - guard let self = self else { return } - - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - - if let data = response.result.value { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - self.openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + guard let self = self else { return } + + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + + if let data = response.result.value { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + self.openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + } } - } - self.openHABSitemapPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } + self.openHABSitemapPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } - self.widgets = self.openHABSitemapPage?.widgets ?? [] + self.widgets = self.openHABSitemapPage?.widgets ?? [] - self.showAlert = self.widgets.isEmpty ? true : false - if refresh { self.loadPage(url: url, - longPolling: true, - refresh: true) } + self.showAlert = self.widgets.isEmpty ? true : false + if refresh { self.loadPage(url: url, + longPolling: true, + refresh: true) } - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - self.errorDescription = error.localizedDescription - self.widgets = [] - self.showAlert = true - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + self.errorDescription = error.localizedDescription + self.widgets = [] + self.showAlert = true + } } currentPageOperation?.resume() } diff --git a/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift b/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift index 12801250c..19a0a5c24 100644 --- a/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift +++ b/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift @@ -73,7 +73,7 @@ class AppMessageService: NSObject, WCSessionDelegate { errorHandler: { (error) in os_log("Error sending message %{PUBLIC}@", log: .watch, type: .info, "\(error)") - }) + }) } @available(watchOSApplicationExtension 2.2, *) From 7c76869831521cef9de58e56525c1207ac84d96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sat, 1 Aug 2020 22:03:20 +0200 Subject: [PATCH 09/78] Moved ItemType/WidgetType to separate file ItemType.swift Taking advantage of enum with raw value of String to be Decodable while graciously handling of unknown enum types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB.xcodeproj/project.pbxproj | 6 ++ openHABCore/Sources/Model/OpenHABWidget.swift | 6 +- openHABCore/Sources/Util/ItemType.swift | 67 +++++++++++++++++++ .../Sources/Util/StringExtension.swift | 34 ---------- 4 files changed, 76 insertions(+), 37 deletions(-) create mode 100644 openHABCore/Sources/Util/ItemType.swift diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 7fe0a85b6..806c084bd 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -95,6 +95,8 @@ DA1C32BA2311CCE200FACFB0 /* JSONData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1C32B92311CCE200FACFB0 /* JSONData.swift */; }; DA21EAE22339621C001AB415 /* Throttler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21EAE12339621C001AB415 /* Throttler.swift */; }; DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA28C361225241DE00AB409C /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + DA2CBDAE24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; + DA2CBDAF24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */; }; DA2E0AA423DC96E9009B0A99 /* EncircledIconWithAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0AA323DC96E9009B0A99 /* EncircledIconWithAction.swift */; }; DA2E0B0E23DCC153009B0A99 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0B0D23DCC152009B0A99 /* MapView.swift */; }; @@ -398,6 +400,7 @@ DA1C32B92311CCE200FACFB0 /* JSONData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONData.swift; sourceTree = ""; }; DA21EAE12339621C001AB415 /* Throttler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Throttler.swift; sourceTree = ""; }; DA28C361225241DE00AB409C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemType.swift; sourceTree = ""; }; DA2DC22F21F2736C00830730 /* openHABTestsSwift.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = openHABTestsSwift.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABJSONParserTests.swift; sourceTree = ""; }; DA2DC23321F2736C00830730 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -704,6 +707,7 @@ 9350F17B2381509300054BA8 /* OSLogExtension.swift */, 9350F1812381514E00054BA8 /* ServerCertificateManager.swift */, 9350F190238151CE00054BA8 /* StringExtension.swift */, + DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */, 9350F193238151F100054BA8 /* Preferences.swift */, DAF4578323D780730018B495 /* UIColorExtension.swift */, 9394102522CB5CDB00EB4255 /* Collection+SafeAccess.swift */, @@ -1624,6 +1628,7 @@ 9350F1822381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579D23D904350018B495 /* UIColorExtension.swift in Sources */, 9350F16323814EC200054BA8 /* OpenHABSitemap.swift in Sources */, + DA2CBDAE24D5FD73003CAE8A /* ItemType.swift in Sources */, 9350F10123814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10423814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F191238151CE00054BA8 /* StringExtension.swift in Sources */, @@ -1657,6 +1662,7 @@ 9350F1832381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579E23D904360018B495 /* UIColorExtension.swift in Sources */, 9350F16423814EC200054BA8 /* OpenHABSitemap.swift in Sources */, + DA2CBDAF24D5FD73003CAE8A /* ItemType.swift in Sources */, 9350F10223814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10523814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F192238151CE00054BA8 /* StringExtension.swift in Sources */, diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index fa1b2425a..cbc23dabf 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -161,12 +161,12 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { 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], visibility: Bool?, switchSupport: Bool?) { + convenience init(widgetId: String, label: String, icon: String, type: WidgetType, 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], visibility: Bool?, switchSupport: Bool?) { self.init() id = widgetId self.widgetId = widgetId self.label = label - self.type = type.toWidgetType() + self.type = type self.icon = icon self.url = url ?? "" self.period = period ?? "" @@ -246,7 +246,7 @@ extension OpenHABWidget { public struct CodingData: Decodable { let widgetId: String let label: String - let type: String + let type: WidgetType let icon: String let url: String? let period: String? diff --git a/openHABCore/Sources/Util/ItemType.swift b/openHABCore/Sources/Util/ItemType.swift new file mode 100644 index 000000000..2e1dc4f1b --- /dev/null +++ b/openHABCore/Sources/Util/ItemType.swift @@ -0,0 +1,67 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +// swiftlint:disable file_types_order +public enum ItemType: String { + case color = "Color" + case contact = "Contact" + case dateTime = "DateTime" + case dimmer = "Dimmer" + case group = "Group" + case image = "Image" + case location = "Location" + case number = "Number" + case numberWithDimension = "NumberWithDimension" + case player = "Player" + case rollershutter = "Rollershutter" + case stringItem = "String" + case switchItem = "Switch" +} + +extension ItemType: Decodable {} + +public enum WidgetType: String { + case chart = "Chart" + case colorpicker = "Colorpicker" + case defaultWidget = "Default" + case frame = "Frame" + case group = "Group" + case image = "Image" + case mapview = "Mapview" + case selection = "Selection" + case setpoint = "Setpoint" + case slider = "Slider" + case switchWidget = "Switch" + case text = "Text" + case video = "Video" + case webview = "Webview" + case unknown = "Unknown" +} + +extension WidgetType: Decodable {} + +// Graciously handling of unknown enum types: https://www.latenightswift.com/2019/02/04/unknown-enum-cases/ +protocol UnknownCaseRepresentable: RawRepresentable, CaseIterable where RawValue: Equatable { + static var unknownCase: Self { get } +} + +extension UnknownCaseRepresentable { + public init(rawValue: RawValue) { + let value = Self.allCases.first { $0.rawValue == rawValue } + self = value ?? Self.unknownCase + } +} + +extension WidgetType: UnknownCaseRepresentable { + static var unknownCase: WidgetType = .unknown +} diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index f08f071fc..1911024b7 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -13,40 +13,6 @@ import Foundation import MapKit import os.log -public enum ItemType: String { - case color = "Color" - case contact = "Contact" - case dateTime = "DateTime" - case dimmer = "Dimmer" - case group = "Group" - case image = "Image" - case location = "Location" - case number = "Number" - case numberWithDimension = "NumberWithDimension" - case player = "Player" - case rollershutter = "Rollershutter" - case stringItem = "String" - case switchItem = "Switch" -} - -public enum WidgetType: String { - case chart = "Chart" - case colorpicker = "Colorpicker" - case defaultWidget = "Default" - case frame = "Frame" - case group = "Group" - case image = "Image" - case mapview = "Mapview" - case selection = "Selection" - case setpoint = "Setpoint" - case slider = "Slider" - case switchWidget = "Switch" - case text = "Text" - case video = "Video" - case webview = "Webview" - case unknown = "Unknown" -} - extension String { var doubleValue: Double { let formatter = NumberFormatter() From 09e6f4ff2770133b7e02c3e21b4647197e1f17dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 2 Aug 2020 09:59:41 +0200 Subject: [PATCH 10/78] Fix for #552: Incorrect OnOff icon state for Color Items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/OpenHABNotificationsViewController.swift | 2 +- openHAB/OpenHABViewController.swift | 2 +- openHAB/SwitchUITableViewCell.swift | 3 ++- openHABCore/Sources/Util/Endpoint.swift | 4 ++-- openHABCore/Sources/Util/StringExtension.swift | 2 +- openHABTestsSwift/OpenHABGeneralTests.swift | 2 +- openHABWatch Extension/Views/Rows/ImageRow.swift | 2 +- openHABWatch Extension/Views/Utils/IconView.swift | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/openHAB/OpenHABNotificationsViewController.swift b/openHAB/OpenHABNotificationsViewController.swift index 9d37fce49..7faeb940a 100644 --- a/openHAB/OpenHABNotificationsViewController.swift +++ b/openHAB/OpenHABNotificationsViewController.swift @@ -114,7 +114,7 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat if let iconUrl = Endpoint.icon(rootUrl: appData!.openHABRootUrl, version: appData!.openHABVersion, icon: notification.icon, - value: "", + state: "", iconType: .png).url { cell?.imageView?.kf.setImage(with: iconUrl, placeholder: UIImage(named: "openHABIcon")) diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 5bac2d6ff..3eb0b0af0 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1036,7 +1036,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { if let urlc = Endpoint.icon(rootUrl: openHABRootUrl, version: appData?.openHABVersion ?? 2, icon: widget?.icon, - value: widget?.item?.state ?? "", + state: widget?.state ?? widget?.item?.state ?? "", iconType: iconType).url { var imageRequest = URLRequest(url: urlc) imageRequest.timeoutInterval = 10.0 diff --git a/openHAB/SwitchUITableViewCell.swift b/openHAB/SwitchUITableViewCell.swift index 24a640581..45a98dc38 100644 --- a/openHAB/SwitchUITableViewCell.swift +++ b/openHAB/SwitchUITableViewCell.swift @@ -9,6 +9,7 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import os.log import UIKit @@ -38,7 +39,7 @@ class SwitchUITableViewCell: GenericUITableViewCell { state = (widget.item?.state) ?? "" } customDetailTextLabel?.text = widget.labelValue ?? "" - widgetSwitch?.isOn = (state == "ON" ? true : false) + widgetSwitch?.isOn = state.parseAsBool() widgetSwitch?.addTarget(self, action: .switchChange, for: .valueChanged) super.displayWidget() } diff --git a/openHABCore/Sources/Util/Endpoint.swift b/openHABCore/Sources/Util/Endpoint.swift index f01c1513c..ff9b47dde 100644 --- a/openHABCore/Sources/Util/Endpoint.swift +++ b/openHABCore/Sources/Util/Endpoint.swift @@ -100,7 +100,7 @@ extension Endpoint { return endpoint } - public static func icon(rootUrl: String, version: Int, icon: String?, value: String, iconType: IconType) -> Endpoint { + public static func icon(rootUrl: String, version: Int, icon: String?, state: String, iconType: IconType) -> Endpoint { guard let icon = icon, !icon.isEmpty else { return Endpoint(baseURL: "", path: "", queryItems: []) } @@ -109,7 +109,7 @@ extension Endpoint { if version == 2 { return Endpoint(baseURL: rootUrl, path: "/icon/\(icon)", - queryItems: [URLQueryItem(name: "state", value: value), + queryItems: [URLQueryItem(name: "state", value: state), URLQueryItem(name: "format", value: (iconType == .png) ? "PNG" : "SVG")]) } else { return Endpoint(baseURL: rootUrl, diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 1911024b7..bb1181511 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -67,7 +67,7 @@ extension String { WidgetType(rawValue: self) } - func parseAsBool() -> Bool { + public func parseAsBool() -> Bool { if self == "ON" { return true } if let brightness = parseAsBrightness() { return brightness != 0 } if let decimalValue = Int(self) { diff --git a/openHABTestsSwift/OpenHABGeneralTests.swift b/openHABTestsSwift/OpenHABGeneralTests.swift index 283551f47..4c023d3e4 100644 --- a/openHABTestsSwift/OpenHABGeneralTests.swift +++ b/openHABTestsSwift/OpenHABGeneralTests.swift @@ -44,7 +44,7 @@ class OpenHABGeneralTests: XCTestCase { let urlc = Endpoint.icon(rootUrl: "http://192.169.2.1", version: 2, icon: "switch", - value: "OFF", + state: "OFF", iconType: .svg).url XCTAssertEqual(urlc, URL(string: "http://192.169.2.1/icon/switch?state=OFF&format=SVG"), "Check endpoint creation") } diff --git a/openHABWatch Extension/Views/Rows/ImageRow.swift b/openHABWatch Extension/Views/Rows/ImageRow.swift index 560f8d2d9..f9af4bcb6 100644 --- a/openHABWatch Extension/Views/Rows/ImageRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRow.swift @@ -42,7 +42,7 @@ struct ImageRow_Previews: PreviewProvider { let iconURL = Endpoint.icon(rootUrl: PreviewConstants.remoteURLString, version: 2, icon: "Switch", - value: "ON", + state: "ON", iconType: .png).url // let widget = UserData().widgets[8] return ImageRow(URL: iconURL) diff --git a/openHABWatch Extension/Views/Utils/IconView.swift b/openHABWatch Extension/Views/Utils/IconView.swift index 349e3587c..bb421d12c 100644 --- a/openHABWatch Extension/Views/Utils/IconView.swift +++ b/openHABWatch Extension/Views/Utils/IconView.swift @@ -23,7 +23,7 @@ struct IconView: View { Endpoint.icon(rootUrl: settings.openHABRootUrl, version: 2, icon: widget.icon, - value: widget.item?.state ?? "", + state: widget.item?.state ?? "", iconType: .png).url } From b5129cc1428961e32c3915e849a3e1878e89c300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 2 Aug 2020 10:03:17 +0200 Subject: [PATCH 11/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 806c084bd..a73726e08 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1858,7 +1858,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1870,7 +1870,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1902,7 +1902,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1914,7 +1914,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1943,7 +1943,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -1962,7 +1962,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -1991,7 +1991,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2009,7 +2009,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2039,7 +2039,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2057,7 +2057,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2089,7 +2089,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2106,7 +2106,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2137,14 +2137,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2176,14 +2176,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2212,7 +2212,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2224,7 +2224,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2254,7 +2254,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2266,7 +2266,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2296,7 +2296,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2308,7 +2308,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2341,7 +2341,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2353,7 +2353,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2494,7 +2494,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2511,7 +2511,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2541,7 +2541,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410446; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2558,7 +2558,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.3.26; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From 06f4fc76d7a9de10f9bde5b49f1f9bbe5a7dd9b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 2 Aug 2020 23:20:47 +0200 Subject: [PATCH 12/78] Fix for #552: Setting icon state - with logic from kotlin app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Gemfile.lock | 85 +++++++++---------- openHAB.xcodeproj/project.pbxproj | 4 + openHAB/OpenHABViewController.swift | 2 +- openHABCore/Sources/Model/OpenHABItem.swift | 4 +- openHABCore/Sources/Model/OpenHABWidget.swift | 27 ++++++ .../Sources/Util/StringExtension.swift | 32 +++---- .../Sources/Util/UIColorExtension.swift | 25 ++++++ openHABTestsSwift/ParseAsTest.swift | 33 +++++++ 8 files changed, 145 insertions(+), 67 deletions(-) create mode 100644 openHABTestsSwift/ParseAsTest.swift diff --git a/Gemfile.lock b/Gemfile.lock index 789de1756..3ba21ab31 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,70 +6,69 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.304.0) - aws-sdk-core (3.94.0) + aws-partitions (1.349.0) + aws-sdk-core (3.104.3) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.30.0) - aws-sdk-core (~> 3, >= 3.71.0) + aws-sdk-kms (1.36.0) + aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.63.0) - aws-sdk-core (~> 3, >= 3.83.0) + aws-sdk-s3 (1.75.0) + aws-sdk-core (~> 3, >= 3.104.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.3) - aws-eventstream (~> 1.0, >= 1.0.2) + aws-sigv4 (1.2.1) + aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.3) claide (1.0.3) colored (1.2) colored2 (3.1.2) commander-fastlane (4.4.6) highline (~> 1.7.2) - declarative (0.0.10) + declarative (0.0.20) declarative-option (0.1.0) - digest-crc (0.5.1) + digest-crc (0.6.1) + rake (~> 13.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) - emoji_regex (1.0.1) - excon (0.73.0) - faraday (0.17.3) + dotenv (2.7.6) + emoji_regex (3.0.0) + excon (0.76.0) + faraday (1.0.1) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) faraday (>= 0.7.4) http-cookie (~> 1.0.0) - faraday_middleware (0.13.1) - faraday (>= 0.7.4, < 1.0) - fastimage (2.1.7) - fastlane (2.146.1) + faraday_middleware (1.0.0) + faraday (~> 1.0) + fastimage (2.2.0) + fastlane (2.154.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.2, < 2.0.0) + babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored commander-fastlane (>= 4.4.6, < 5.0.0) dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 2.0) + emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) - faraday (~> 0.17) + faraday (~> 1.0) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.13.1) + faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.29.2, < 0.37.0) + google-api-client (>= 0.37.0, < 0.39.0) google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) - jwt (~> 2.1.0) + jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) - multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) - public_suffix (~> 2.0.0) - rubyzip (>= 1.3.0, < 2.0.0) + rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) @@ -84,7 +83,7 @@ GEM fastlane-plugin-changelog (0.15.0) fastlane-plugin-versioning (0.4.3) gh_inspector (1.1.3) - google-api-client (0.36.4) + google-api-client (0.38.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) @@ -95,17 +94,17 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.1) + google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.0.0) - google-cloud-storage (1.26.0) + google-cloud-errors (1.0.1) + google-cloud-storage (1.27.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.12.0) + googleauth (0.13.1) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -117,26 +116,26 @@ GEM domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.4.0) - json (2.3.0) - jwt (2.1.0) + json (2.3.1) + jwt (2.2.1) memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) - multi_json (1.14.1) - multi_xml (0.6.0) + multi_json (1.15.0) multipart-post (2.0.0) - nanaimo (0.2.6) + nanaimo (0.3.0) naturally (2.2.0) - os (1.1.0) + os (1.1.1) plist (3.5.0) - public_suffix (2.0.5) + public_suffix (4.0.5) + rake (13.0.1) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) retriable (3.1.2) rouge (2.0.7) - rubyzip (1.3.0) + rubyzip (2.3.0) security (0.1.3) signet (0.14.0) addressable (~> 2.3) @@ -151,7 +150,7 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) tty-cursor (0.7.1) - tty-screen (0.7.1) + tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) @@ -160,12 +159,12 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.16.0) + xcodeproj (1.17.1) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.6) + nanaimo (~> 0.3.0) xcpretty (0.3.0) rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.0) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index a73726e08..791ec4d63 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -97,6 +97,7 @@ DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA28C361225241DE00AB409C /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; DA2CBDAE24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; DA2CBDAF24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; + DA2CBDB124D7562C003CAE8A /* ParseAsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */; }; DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */; }; DA2E0AA423DC96E9009B0A99 /* EncircledIconWithAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0AA323DC96E9009B0A99 /* EncircledIconWithAction.swift */; }; DA2E0B0E23DCC153009B0A99 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0B0D23DCC152009B0A99 /* MapView.swift */; }; @@ -401,6 +402,7 @@ DA21EAE12339621C001AB415 /* Throttler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Throttler.swift; sourceTree = ""; }; DA28C361225241DE00AB409C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemType.swift; sourceTree = ""; }; + DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAsTest.swift; sourceTree = ""; }; DA2DC22F21F2736C00830730 /* openHABTestsSwift.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = openHABTestsSwift.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABJSONParserTests.swift; sourceTree = ""; }; DA2DC23321F2736C00830730 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -829,6 +831,7 @@ DA966477232EDEAD00CB418B /* MockURLProtocol.swift */, DACC72E024CE14FB007EFAE3 /* restAPI.json */, DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */, + DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */, ); path = openHABTestsSwift; sourceTree = ""; @@ -1730,6 +1733,7 @@ DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */, DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */, DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */, + DA2CBDB124D7562C003CAE8A /* ParseAsTest.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 3eb0b0af0..42f083dd3 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1036,7 +1036,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { if let urlc = Endpoint.icon(rootUrl: openHABRootUrl, version: appData?.openHABVersion ?? 2, icon: widget?.icon, - state: widget?.state ?? widget?.item?.state ?? "", + state: widget?.iconState() ?? "", iconType: iconType).url { var imageRequest = URLRequest(url: urlc) imageRequest.timeoutInterval = 10.0 diff --git a/openHABCore/Sources/Model/OpenHABItem.swift b/openHABCore/Sources/Model/OpenHABItem.swift index e7c8e2a73..ca936653f 100644 --- a/openHABCore/Sources/Model/OpenHABItem.swift +++ b/openHABCore/Sources/Model/OpenHABItem.swift @@ -66,7 +66,7 @@ public final class OpenHABItem: NSObject, CommItem { } } - func isOfTypeOrGroupType(_ type: ItemType) -> Bool { + public func isOfTypeOrGroupType(_ type: ItemType) -> Bool { self.type == type || groupType == type } } @@ -176,7 +176,7 @@ extension OpenHABItem.CodingData { extension CGFloat { init(state string: String, divisor: Float) { let numberFormatter = NumberFormatter() - numberFormatter.locale = Locale(identifier: "EN") + numberFormatter.locale = Locale(identifier: "US") if let number = numberFormatter.number(from: string) { self.init(number.floatValue / divisor) } else { diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index cbc23dabf..1cf39c7a4 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -157,6 +157,33 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public func mappingIndex(byCommand command: String?) -> Int? { mappingsOrItemOptions.firstIndex { $0.command == command } } + + public func iconState() -> String { + var iconState = item?.state ?? "" + if let item = item, let itemState = item.state { + if item.isOfTypeOrGroupType(.color) { + // For items that control a color item fetch the correct icon + if type == .slider || (type == .switchWidget && mappings.isEmpty) { + if let brightness = itemState.parseAsBrightness() { + iconState = String(brightness) + if type == .switchWidget { + iconState = iconState == "0" ? "OFF" : "ON" + } + } else { + iconState = "OFF" + } + } else if let color = itemState.parseAsUIColor() { + iconState = "#\(color.toHex() ?? "000000")" + } + } else if type == .switchWidget, mappings.isEmpty, !item.isOfTypeOrGroupType(.rollershutter) { + // For switch items without mappings (just ON and OFF) that control a dimmer item + // and which are not ON or OFF already, set the state to "OFF" instead of 0 + // or to "ON" to fetch the correct icon + iconState = (itemState == "0" || itemState == "OFF") ? "OFF" : "ON" + } + } + return iconState + } } extension OpenHABWidget { diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index bb1181511..1a226d4e8 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -89,29 +89,19 @@ extension String { } } - func parseAsUIColor() -> UIColor { - if self == "Uninitialized" { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } else { - let values = components(separatedBy: ",") - if values.count == 3 { - let hue = CGFloat(state: values[0], divisor: 360) - let saturation = CGFloat(state: values[1], divisor: 100) - let brightness = CGFloat(state: values[2], divisor: 100) - os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) - return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) - } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } - } + public func parseAsUIColor() -> UIColor? { + let values = components(separatedBy: ",") + guard values.count == 3 else { return nil } + let hue = CGFloat(state: values[0], divisor: 360) + let saturation = CGFloat(state: values[1], divisor: 100) + let brightness = CGFloat(state: values[2], divisor: 100) + os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) + return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) } - func parseAsBrightness() -> Int? { + public func parseAsBrightness() -> Int? { let values = components(separatedBy: ",") - if values.count == 3 { - return Int(values[2].stateAsDouble().rounded()) - } else { - return nil - } + guard values.count == 3 else { return nil } + return Int(values[2].stateAsDouble().rounded()) } } diff --git a/openHABCore/Sources/Util/UIColorExtension.swift b/openHABCore/Sources/Util/UIColorExtension.swift index 3e25d71e4..57068c805 100644 --- a/openHABCore/Sources/Util/UIColorExtension.swift +++ b/openHABCore/Sources/Util/UIColorExtension.swift @@ -201,4 +201,29 @@ public extension UIColor { self.init(red: red, green: green, blue: blue, alpha: 1) } + + // Inspired by https://cocoacasts.com/from-hex-to-uicolor-and-back-in-swift + + // MARK: - From UIColor to String + + func toHex(alpha: Bool = false) -> String? { + guard let components = cgColor.components, components.count >= 3 else { + return nil + } + + let red = Float(components[0]) + let green = Float(components[1]) + let blue = Float(components[2]) + var a = Float(1.0) + + if components.count >= 4 { + a = Float(components[3]) + } + + if alpha { + return String(format: "%02lX%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255), lroundf(a * 255)) + } else { + return String(format: "%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255)) + } + } } diff --git a/openHABTestsSwift/ParseAsTest.swift b/openHABTestsSwift/ParseAsTest.swift new file mode 100644 index 000000000..b8a7f7ea6 --- /dev/null +++ b/openHABTestsSwift/ParseAsTest.swift @@ -0,0 +1,33 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import XCTest + +@testable import openHAB +@testable import OpenHABCore + +class ParseAsTest: XCTestCase { + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + + XCTAssertFalse("10,10,0".parseAsBool()) + XCTAssertTrue("10,10,50".parseAsBool()) + } +} From c84ae0c7a880898e7aa0ae1b9d445141ba8d4da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Mon, 3 Aug 2020 21:51:48 +0200 Subject: [PATCH 13/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 791ec4d63..9a6ba46d5 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1862,7 +1862,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1874,7 +1874,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1906,7 +1906,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1918,7 +1918,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1947,7 +1947,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -1966,7 +1966,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -1995,7 +1995,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2013,7 +2013,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2043,7 +2043,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2061,7 +2061,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2093,7 +2093,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2110,7 +2110,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2141,14 +2141,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2180,14 +2180,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2216,7 +2216,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2228,7 +2228,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2258,7 +2258,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2270,7 +2270,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2300,7 +2300,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2312,7 +2312,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2345,7 +2345,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2357,7 +2357,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2498,7 +2498,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2515,7 +2515,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2545,7 +2545,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410446; + CURRENT_PROJECT_VERSION = 1580410447; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2562,7 +2562,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.26; + MARKETING_VERSION = 2.3.27; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From 9d628edaa4c49a20cc24c2ca5836a597cb617a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Tue, 4 Aug 2020 23:10:26 +0200 Subject: [PATCH 14/78] Reworked dequeueReusableCell in OpenHABViewController to higher level of abstraction Nested enums for WidgetType and ItemType into OpenHABWidget/OpenHABItem respectively (cleanup of UnknownCaseRepresentable) UIColor.black instead of hue=saturation=brightness=0 Aligning SwiftUI struct for Setpoint to UoM handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB.xcodeproj/project.pbxproj | 12 ++-- openHAB/OpenHABViewController.swift | 11 +-- openHAB/SetpointUITableViewCell.swift | 4 -- openHABCore/Sources/Model/NumberState.swift | 4 +- openHABCore/Sources/Model/OpenHABItem.swift | 62 +++++++---------- openHABCore/Sources/Model/OpenHABWidget.swift | 24 +++++++ openHABCore/Sources/Util/Endpoint.swift | 2 +- openHABCore/Sources/Util/ItemType.swift | 67 ------------------- .../Sources/Util/StringExtension.swift | 21 ++++-- .../Util/UnknownCaseRepresentable.swift | 24 +++++++ openHABTestsSwift/NumberStateTest.swift | 35 ++++++++-- .../Views/Rows/SetpointRow.swift | 51 +++++--------- .../Views/Rows/SliderRow.swift | 6 +- .../Model/ObservableOpenHABWidget.swift | 42 ++++++++++-- 14 files changed, 188 insertions(+), 177 deletions(-) delete mode 100644 openHABCore/Sources/Util/ItemType.swift create mode 100644 openHABCore/Sources/Util/UnknownCaseRepresentable.swift diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 9a6ba46d5..f1eb21f59 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -95,8 +95,8 @@ DA1C32BA2311CCE200FACFB0 /* JSONData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1C32B92311CCE200FACFB0 /* JSONData.swift */; }; DA21EAE22339621C001AB415 /* Throttler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21EAE12339621C001AB415 /* Throttler.swift */; }; DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA28C361225241DE00AB409C /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - DA2CBDAE24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; - DA2CBDAF24D5FD73003CAE8A /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */; }; + DA2CBDAE24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */; }; + DA2CBDAF24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */; }; DA2CBDB124D7562C003CAE8A /* ParseAsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */; }; DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */; }; DA2E0AA423DC96E9009B0A99 /* EncircledIconWithAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0AA323DC96E9009B0A99 /* EncircledIconWithAction.swift */; }; @@ -401,7 +401,7 @@ DA1C32B92311CCE200FACFB0 /* JSONData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONData.swift; sourceTree = ""; }; DA21EAE12339621C001AB415 /* Throttler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Throttler.swift; sourceTree = ""; }; DA28C361225241DE00AB409C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemType.swift; sourceTree = ""; }; + DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownCaseRepresentable.swift; sourceTree = ""; }; DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAsTest.swift; sourceTree = ""; }; DA2DC22F21F2736C00830730 /* openHABTestsSwift.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = openHABTestsSwift.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABJSONParserTests.swift; sourceTree = ""; }; @@ -709,7 +709,7 @@ 9350F17B2381509300054BA8 /* OSLogExtension.swift */, 9350F1812381514E00054BA8 /* ServerCertificateManager.swift */, 9350F190238151CE00054BA8 /* StringExtension.swift */, - DA2CBDAD24D5FD73003CAE8A /* ItemType.swift */, + DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */, 9350F193238151F100054BA8 /* Preferences.swift */, DAF4578323D780730018B495 /* UIColorExtension.swift */, 9394102522CB5CDB00EB4255 /* Collection+SafeAccess.swift */, @@ -1631,7 +1631,7 @@ 9350F1822381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579D23D904350018B495 /* UIColorExtension.swift in Sources */, 9350F16323814EC200054BA8 /* OpenHABSitemap.swift in Sources */, - DA2CBDAE24D5FD73003CAE8A /* ItemType.swift in Sources */, + DA2CBDAE24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */, 9350F10123814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10423814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F191238151CE00054BA8 /* StringExtension.swift in Sources */, @@ -1665,7 +1665,7 @@ 9350F1832381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579E23D904360018B495 /* UIColorExtension.swift in Sources */, 9350F16423814EC200054BA8 /* OpenHABSitemap.swift in Sources */, - DA2CBDAF24D5FD73003CAE8A /* ItemType.swift in Sources */, + DA2CBDAF24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */, 9350F10223814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10523814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F192238151CE00054BA8 /* StringExtension.swift in Sources */, diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 42f083dd3..5d12b31a5 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -992,14 +992,13 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { cell = tableView.dequeueReusableCell(for: indexPath) as FrameUITableViewCell case .switchWidget: // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 - if widget?.mappings.count ?? 0 > 0 { + if !(widget?.mappings ?? []).isEmpty { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell - // RollershutterItem changed to Rollershutter in later builds of OH2 - } else if let type = widget?.item?.type, type == .switchItem { + } else if widget?.item?.isOfTypeOrGroupType(.switchItem) ?? false { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell - } else if let type = widget?.item?.type, type == .rollershutter || (type == .group && widget?.item?.groupType == .rollershutter) { + } else if widget?.item?.isOfTypeOrGroupType(.rollershutter) ?? false { cell = tableView.dequeueReusableCell(for: indexPath) as RollershutterUITableViewCell - } else if widget?.item?.stateDescription?.options.count ?? 0 > 0 { + } else if !(widget?.mappingsOrItemOptions ?? []).isEmpty { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell } else { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell @@ -1027,6 +1026,8 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { cell = tableView.dequeueReusableCell(for: indexPath) as WebUITableViewCell case .mapview: cell = (tableView.dequeueReusableCell(withIdentifier: openHABViewControllerMapViewCellReuseIdentifier) as? MapViewTableViewCell)! + case .group, .text: + cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell default: cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell } diff --git a/openHAB/SetpointUITableViewCell.swift b/openHAB/SetpointUITableViewCell.swift index 341790a5e..60cbd0fc9 100644 --- a/openHAB/SetpointUITableViewCell.swift +++ b/openHAB/SetpointUITableViewCell.swift @@ -15,10 +15,6 @@ import os.log import UIKit class SetpointUITableViewCell: GenericUITableViewCell { - private var isIntStep: Bool { - widget.step.truncatingRemainder(dividingBy: 1) == 0 - } - @IBOutlet private var downButton: DynamicButton! @IBOutlet private var upButton: DynamicButton! diff --git a/openHABCore/Sources/Model/NumberState.swift b/openHABCore/Sources/Model/NumberState.swift index 825a75dd1..08111a0c1 100644 --- a/openHABCore/Sources/Model/NumberState.swift +++ b/openHABCore/Sources/Model/NumberState.swift @@ -20,7 +20,7 @@ public struct NumberState: CustomStringConvertible, Equatable { private(set) var unit: String? = "" private(set) var format: String? = "" - func toString(locale: Locale?) -> String { + public func toString(locale: Locale?) -> String { if let format = format, format.isEmpty == false { let actualFormat = format.replacingOccurrences(of: "%unit%", with: unit ?? "") if format.contains("%d") == true { @@ -36,7 +36,7 @@ public struct NumberState: CustomStringConvertible, Equatable { } } - func formatValue() -> String { + public func formatValue() -> String { String(value) } diff --git a/openHABCore/Sources/Model/OpenHABItem.swift b/openHABCore/Sources/Model/OpenHABItem.swift index ca936653f..0358f5839 100644 --- a/openHABCore/Sources/Model/OpenHABItem.swift +++ b/openHABCore/Sources/Model/OpenHABItem.swift @@ -14,6 +14,22 @@ import Fuzi import os.log import UIKit public final class OpenHABItem: NSObject, CommItem { + public enum ItemType: String { + case color = "Color" + case contact = "Contact" + case dateTime = "DateTime" + case dimmer = "Dimmer" + case group = "Group" + case image = "Image" + case location = "Location" + case number = "Number" + case numberWithDimension = "NumberWithDimension" + case player = "Player" + case rollershutter = "Rollershutter" + case stringItem = "String" + case switchItem = "Switch" + } + public var type: ItemType? public var groupType: ItemType? public var name = "" @@ -24,6 +40,7 @@ public final class OpenHABItem: NSObject, CommItem { public var readOnly = false public var members: [OpenHABItem] = [] public var category = "" + public var options: [OpenHABOptions] = [] var canBeToggled: Bool { isOfTypeOrGroupType(ItemType.color) || @@ -34,7 +51,7 @@ public final class OpenHABItem: NSObject, CommItem { isOfTypeOrGroupType(ItemType.player) } - public init(name: String, type: String, state: String?, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?, members: [OpenHABItem], category: String?) { + public init(name: String, type: String, state: String?, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?, members: [OpenHABItem], category: String?, options: [OpenHABOptions]?) { self.name = name self.type = type.toItemType() if let state = state, (state == "NULL" || state == "UNDEF" || state.caseInsensitiveCompare("undefined") == .orderedSame) { @@ -49,6 +66,7 @@ public final class OpenHABItem: NSObject, CommItem { readOnly = stateDescription?.readOnly ?? false self.members = members self.category = category ?? "" + self.options = options ?? [] } public init(xml xmlElement: XMLElement) { @@ -71,40 +89,7 @@ public final class OpenHABItem: NSObject, CommItem { } } -extension String { - public func stateAsDouble() -> Double { - numberValue?.doubleValue ?? 0 - } - - public func stateAsUIColor() -> UIColor { - if self == "Uninitialized" { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } else { - let values = components(separatedBy: ",") - if values.count == 3 { - let hue = CGFloat(state: values[0], divisor: 360) - let saturation = CGFloat(state: values[1], divisor: 100) - let brightness = CGFloat(state: values[2], divisor: 100) - os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) - return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) - } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } - } - } - - public func stateAsLocation() -> CLLocation { - // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') - let locationComponents = components(separatedBy: ",") - if locationComponents.count >= 2 { - let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) - let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) - - return CLLocation(latitude: latitude, longitude: longitude) - } - return CLLocation(latitude: 0.0, longitude: 0.0) - } -} +extension OpenHABItem.ItemType: Decodable {} extension OpenHABItem { public func stateAsDouble() -> Double { @@ -125,10 +110,10 @@ extension OpenHABItem { os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + return .black } } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + return .black } } @@ -162,6 +147,7 @@ extension OpenHABItem { let stateDescription: OpenHABStateDescription.CodingData? let members: [OpenHABItem.CodingData]? let category: String? + let options: [OpenHABOptions]? } } @@ -169,7 +155,7 @@ extension OpenHABItem.CodingData { public var openHABItem: OpenHABItem { let mappedMembers = members?.map(\.openHABItem) ?? [] - return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, members: mappedMembers, category: category) + return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, members: mappedMembers, category: category, options: options) } } diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index 1cf39c7a4..8f988954c 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -50,6 +50,24 @@ protocol Widget: AnyObject { } public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { + public enum WidgetType: String { + case chart = "Chart" + case colorpicker = "Colorpicker" + case defaultWidget = "Default" + case frame = "Frame" + case group = "Group" + case image = "Image" + case mapview = "Mapview" + case selection = "Selection" + case setpoint = "Setpoint" + case slider = "Slider" + case switchWidget = "Switch" + case text = "Text" + case video = "Video" + case webview = "Webview" + case unknown = "Unknown" + } + public var id: String = "" public var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? @@ -186,6 +204,12 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { } } +extension OpenHABWidget.WidgetType: Decodable {} + +extension OpenHABWidget.WidgetType: UnknownCaseRepresentable { + static var unknownCase: OpenHABWidget.WidgetType = .unknown +} + extension OpenHABWidget { // This is an ugly initializer convenience init(widgetId: String, label: String, icon: String, type: WidgetType, 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], visibility: Bool?, switchSupport: Bool?) { diff --git a/openHABCore/Sources/Util/Endpoint.swift b/openHABCore/Sources/Util/Endpoint.swift index ff9b47dde..3017be273 100644 --- a/openHABCore/Sources/Util/Endpoint.swift +++ b/openHABCore/Sources/Util/Endpoint.swift @@ -73,7 +73,7 @@ extension Endpoint { } // swiftlint:disable:next function_parameter_count - public static func chart(rootUrl: String, period: String?, type: ItemType?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> Endpoint { + public static func chart(rootUrl: String, period: String?, type: OpenHABItem.ItemType?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> Endpoint { let random = Int.random(in: 0 ..< 1000) var endpoint = Endpoint(baseURL: rootUrl, path: "/chart", diff --git a/openHABCore/Sources/Util/ItemType.swift b/openHABCore/Sources/Util/ItemType.swift deleted file mode 100644 index 2e1dc4f1b..000000000 --- a/openHABCore/Sources/Util/ItemType.swift +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2010-2020 Contributors to the openHAB project -// -// See the NOTICE file(s) distributed with this work for additional -// information. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0 -// -// SPDX-License-Identifier: EPL-2.0 - -import Foundation - -// swiftlint:disable file_types_order -public enum ItemType: String { - case color = "Color" - case contact = "Contact" - case dateTime = "DateTime" - case dimmer = "Dimmer" - case group = "Group" - case image = "Image" - case location = "Location" - case number = "Number" - case numberWithDimension = "NumberWithDimension" - case player = "Player" - case rollershutter = "Rollershutter" - case stringItem = "String" - case switchItem = "Switch" -} - -extension ItemType: Decodable {} - -public enum WidgetType: String { - case chart = "Chart" - case colorpicker = "Colorpicker" - case defaultWidget = "Default" - case frame = "Frame" - case group = "Group" - case image = "Image" - case mapview = "Mapview" - case selection = "Selection" - case setpoint = "Setpoint" - case slider = "Slider" - case switchWidget = "Switch" - case text = "Text" - case video = "Video" - case webview = "Webview" - case unknown = "Unknown" -} - -extension WidgetType: Decodable {} - -// Graciously handling of unknown enum types: https://www.latenightswift.com/2019/02/04/unknown-enum-cases/ -protocol UnknownCaseRepresentable: RawRepresentable, CaseIterable where RawValue: Equatable { - static var unknownCase: Self { get } -} - -extension UnknownCaseRepresentable { - public init(rawValue: RawValue) { - let value = Self.allCases.first { $0.rawValue == rawValue } - self = value ?? Self.unknownCase - } -} - -extension WidgetType: UnknownCaseRepresentable { - static var unknownCase: WidgetType = .unknown -} diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 1a226d4e8..2f2ce6cb3 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -44,7 +44,11 @@ extension String { return formatter.number(from: filter("01234567890.-".contains)) } - func toItemType() -> ItemType? { + var asDouble: Double { + numberValue?.doubleValue ?? 0 + } + + func toItemType() -> OpenHABItem.ItemType? { var typeString: String = self // Earlier OH2 versions returned e.g. 'Switch' as 'SwitchItem' if hasSuffix("Item") { @@ -60,11 +64,11 @@ extension String { return .numberWithDimension } - return ItemType(rawValue: typeString) + return OpenHABItem.ItemType(rawValue: typeString) } - func toWidgetType() -> WidgetType? { - WidgetType(rawValue: self) + func toWidgetType() -> OpenHABWidget.WidgetType? { + OpenHABWidget.WidgetType(rawValue: self) } public func parseAsBool() -> Bool { @@ -77,7 +81,7 @@ extension String { } } - func parseAsNumber(format: String? = nil) -> NumberState { + public func parseAsNumber(format: String? = nil) -> NumberState { switch self { case "ON": return NumberState(value: 100.0) case "OFF": return NumberState(value: 0.0) @@ -85,11 +89,14 @@ extension String { let components = split(separator: " ").map { String($0) } let number = String(components[safe: 0] ?? "") let unit = components[safe: 1] - return NumberState(value: number.stateAsDouble(), unit: unit, format: format) + return NumberState(value: number.asDouble, unit: unit, format: format) } } public func parseAsUIColor() -> UIColor? { + guard self != "Uninitialized" else { + return .black + } let values = components(separatedBy: ",") guard values.count == 3 else { return nil } let hue = CGFloat(state: values[0], divisor: 360) @@ -102,6 +109,6 @@ extension String { public func parseAsBrightness() -> Int? { let values = components(separatedBy: ",") guard values.count == 3 else { return nil } - return Int(values[2].stateAsDouble().rounded()) + return Int(values[2].asDouble.rounded()) } } diff --git a/openHABCore/Sources/Util/UnknownCaseRepresentable.swift b/openHABCore/Sources/Util/UnknownCaseRepresentable.swift new file mode 100644 index 000000000..244899033 --- /dev/null +++ b/openHABCore/Sources/Util/UnknownCaseRepresentable.swift @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +// Graciously handling of unknown enum types: https://www.latenightswift.com/2019/02/04/unknown-enum-cases/ +protocol UnknownCaseRepresentable: RawRepresentable, CaseIterable where RawValue: Equatable { + static var unknownCase: Self { get } +} + +extension UnknownCaseRepresentable { + public init(rawValue: RawValue) { + let value = Self.allCases.first { $0.rawValue == rawValue } + self = value ?? Self.unknownCase + } +} diff --git a/openHABTestsSwift/NumberStateTest.swift b/openHABTestsSwift/NumberStateTest.swift index ced482b06..58a3b1b22 100644 --- a/openHABTestsSwift/NumberStateTest.swift +++ b/openHABTestsSwift/NumberStateTest.swift @@ -36,15 +36,15 @@ class NumberStateTest: XCTestCase { } func testToItemType() throws { - XCTAssertEqual("NumberItem".toItemType(), ItemType.number) - XCTAssertEqual("Number:Temperature".toItemType(), ItemType.numberWithDimension) - XCTAssertEqual("String".toItemType(), ItemType.stringItem) + XCTAssertEqual("NumberItem".toItemType(), OpenHABItem.ItemType.number) + XCTAssertEqual("Number:Temperature".toItemType(), OpenHABItem.ItemType.numberWithDimension) + XCTAssertEqual("String".toItemType(), OpenHABItem.ItemType.stringItem) XCTAssertEqual("blabla".toItemType(), nil) } func testToWidgetType() throws { - XCTAssertEqual("Colorpicker".toWidgetType(), WidgetType.colorpicker) - XCTAssertEqual("colorpicker".toWidgetType(), WidgetType.unknown) + XCTAssertEqual("Colorpicker".toWidgetType(), OpenHABWidget.WidgetType.colorpicker) + XCTAssertEqual("colorpicker".toWidgetType(), OpenHABWidget.WidgetType.unknown) } func testParseAs() throws { @@ -59,7 +59,30 @@ class NumberStateTest: XCTestCase { XCTAssertEqual("OFF".parseAsNumber(), NumberState(value: 0.0)) XCTAssertEqual("24.4 °F".parseAsNumber(), NumberState(value: 24.4, unit: "°F", format: nil)) XCTAssertEqual("24.4 °F".parseAsNumber(format: "%.f"), NumberState(value: 24.4, unit: "°F", format: "%.f")) - XCTAssertEqual("Uninitialized".parseAsUIColor(), UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0)) + let col1 = "Uninitialized".parseAsUIColor() + let col2 = UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + XCTAssert(col1!.equals(col2)) XCTAssertEqual("360,100,100".parseAsUIColor(), UIColor(hue: CGFloat(state: "360", divisor: 360), saturation: CGFloat(state: "100", divisor: 100), brightness: CGFloat(state: "100", divisor: 100), alpha: 1.0)) } } + +extension UIColor { + func equals(_ rhs: UIColor) -> Bool { + var lhsR: CGFloat = 0 + var lhsG: CGFloat = 0 + var lhsB: CGFloat = 0 + var lhsA: CGFloat = 0 + getRed(&lhsR, green: &lhsG, blue: &lhsB, alpha: &lhsA) + + var rhsR: CGFloat = 0 + var rhsG: CGFloat = 0 + var rhsB: CGFloat = 0 + var rhsA: CGFloat = 0 + rhs.getRed(&rhsR, green: &rhsG, blue: &rhsB, alpha: &rhsA) + + return lhsR == rhsR && + lhsG == rhsG && + lhsB == rhsB && + lhsA == rhsA + } +} diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index 59b8f4a4f..13c63c9ce 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -54,43 +54,28 @@ struct SetpointRow: View { } } - func decreaseValue() { - os_log("down button pressed", log: .viewCycle, type: .info) - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() - widget.step - newValue = max(newValue, widget.minValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() - Int(widget.step) - newValue = max(newValue, Int(widget.minValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } + private func handleUpDown(down: Bool) { + var numberState = widget.stateValueAsNumberState + let stateValue = numberState?.value ?? widget.minValue + let newValue: Double + switch down { + case true: + newValue = stateValue - widget.step + case false: + newValue = stateValue + widget.step + } + if newValue >= widget.minValue, newValue <= widget.maxValue { + numberState?.value = newValue + widget.sendItemUpdate(state: numberState) } } - func increaseValue() { - os_log("up button pressed", log: .viewCycle, type: .info) + func decreaseValue() { + handleUpDown(down: true) + } - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() + widget.step - newValue = min(newValue, widget.maxValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() + Int(widget.step) - newValue = min(newValue, Int(widget.maxValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + func increaseValue() { + handleUpDown(down: false) } } diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index cf986d0c5..03e5b8ea3 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -20,13 +20,13 @@ struct SliderRow: View { var body: some View { let valueBinding = Binding(get: { - guard case let .slider(value) = self.widget.stateEnumBinding else { return 0 } - return value + self.widget.adjustedValue }, set: { os_log("Slider new value = %g", log: .default, type: .info, $0) self.widget.sendCommand($0.valueText(step: self.widget.step)) - self.widget.stateEnumBinding = .slider($0) + + // self.widget.stateEnumBinding = .slider($0) }) return diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 92376ed93..92813a942 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -21,7 +21,7 @@ import os.log enum WidgetTypeEnum { case switcher(Bool) - case slider(Double) + case slider // case segmented(Int) case unassigned case rollershutter @@ -71,6 +71,8 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO var mappings: [OpenHABWidgetMapping] = [] var image: UIImage? var widgets: [ObservableOpenHABWidget] = [] + public var visibility = true + public var switchSupport = false @Published var stateEnumBinding: WidgetTypeEnum = .unassigned @@ -101,6 +103,22 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } + public var stateValueAsBool: Bool? { + item?.state?.parseAsBool() + } + + public var stateValueAsBrightness: Int? { + item?.state?.parseAsBrightness() + } + + public var stateValueAsUIColor: UIColor? { + item?.state?.parseAsUIColor() + } + + public var stateValueAsNumberState: NumberState? { + item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) + } + var adjustedValue: Double { if let item = item { return adj(item.stateAsDouble()) @@ -117,11 +135,11 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 if !mappings.isEmpty { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) - } else if let type = item?.type, type == .switchItem { + } else if item?.isOfTypeOrGroupType(.switchItem) ?? false { return .switcher(item?.state == "ON" ? true : false) - } else if let type = item?.type, type == .rollershutter || (type == .group && item?.groupType == .rollershutter) { + } else if item?.isOfTypeOrGroupType(.rollershutter) ?? false { return .rollershutter - } else if item?.stateDescription?.options.count ?? 0 > 0 { + } else if !mappingsOrItemOptions.isEmpty { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) } else { return .switcher(item?.state == "ON" ? true : false) @@ -129,7 +147,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO case "Setpoint": return .setpoint case "Slider": - return .slider(adjustedValue) + return .slider // (adjustedValue) case "Selection": return .selection case "Colorpicker": @@ -149,6 +167,20 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } + public func sendItemUpdate(state: NumberState?) { + guard let item = item, let state = state else { + os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) + return + } + if item.isOfTypeOrGroupType(.numberWithDimension) { + // For number items, include unit (if present) in command + sendCommand(state.toString(locale: Locale(identifier: "US"))) + } else { + // For all other items, send the plain value + sendCommand(state.formatValue()) + } + } + func sendCommandDouble(_ command: Double) { sendCommand(String(command)) } From d2c1632ae460ea8b16fb91d42e51a5fec0a3be3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 16 Aug 2020 16:22:45 +0200 Subject: [PATCH 15/78] Replacing a != "" by !a.isEmpty Replacing (a?.count ?? 0) > 0 by !(a ?? "").isEmpty Decoding OpenHABServerProperties Handling of sliders of type color Detecting server version on /rest instead of /rest/bindings - Addressing #526 Renaming UserDefault to UserDefaultsBacked watchOS: though pathMonitor is accessible in watchOS it is ignored MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB.xcodeproj/project.pbxproj | 10 +++++ .../xcshareddata/xcschemes/openHAB.xcscheme | 11 +---- .../xcschemes/openHABTestsSwift.xcscheme | 2 +- .../xcschemes/openHABUITests.xcscheme | 11 +---- .../openHABWatch (Notification).xcscheme | 31 ++++--------- .../xcschemes/openHABWatch.xcscheme | 27 +++--------- .../openHABWatchSwift (Complication).xcscheme | 27 +++--------- openHAB/AppDelegate.swift | 2 +- openHAB/GenericUITableViewCell.swift | 4 +- .../OpenHABDrawerTableViewController.swift | 2 +- openHAB/OpenHABTracker.swift | 2 +- openHAB/OpenHABViewController.swift | 20 +++++++-- openHAB/SliderUITableViewCell.swift | 41 +++++++++++++----- .../Model/OpenHABServerProperties.swift | 35 +++++++++++++++ openHABCore/Sources/Util/Endpoint.swift | 2 +- openHABCore/Sources/Util/Preferences.swift | 7 --- openHABTestsSwift/NumberStateTest.swift | 2 + .../OpenHABJSONParserTests.swift | 25 +++++++++-- .../OpenHABWatchTracker.swift | 41 +++++++++++++++--- .../PreferencesHostingController.swift | 1 + .../Views/PreferencesSwiftUIView.swift | 3 +- .../Views/Utils/DetailTextLabelView.swift | 2 +- .../Views/Utils/TextLabelView.swift | 2 +- .../Model/ObservableOpenHABDataObject.swift | 40 ++++------------- .../Model/UserDefaultsBacked.swift | 36 ++++++++++++++++ .../openHABWatch Extension/UserData.swift | 43 ++++++++----------- 26 files changed, 248 insertions(+), 181 deletions(-) create mode 100644 openHABCore/Sources/Model/OpenHABServerProperties.swift create mode 100644 openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index f1eb21f59..3297a64d1 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -93,6 +93,8 @@ DA15BFBD23C6726400BD8ADA /* ObservableOpenHABDataObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA15BFBC23C6726400BD8ADA /* ObservableOpenHABDataObject.swift */; }; DA19E25B22FD801D002F8F2F /* OpenHABGeneralTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA19E25A22FD801D002F8F2F /* OpenHABGeneralTests.swift */; }; DA1C32BA2311CCE200FACFB0 /* JSONData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1C32B92311CCE200FACFB0 /* JSONData.swift */; }; + DA1EAECF24E94871008A6B22 /* OpenHABServerProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */; }; + DA1EAED024E94871008A6B22 /* OpenHABServerProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */; }; DA21EAE22339621C001AB415 /* Throttler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21EAE12339621C001AB415 /* Throttler.swift */; }; DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA28C361225241DE00AB409C /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; DA2CBDAE24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */; }; @@ -116,6 +118,7 @@ DA88F8C622EC377200B408E5 /* ReleaseNotes.md in Resources */ = {isa = PBXBuildFile; fileRef = DA88F8C522EC377100B408E5 /* ReleaseNotes.md */; }; DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA966477232EDEAD00CB418B /* MockURLProtocol.swift */; }; DA96647A232EE3C200CB418B /* RESTAPITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA966479232EE3C200CB418B /* RESTAPITest.swift */; }; + DA9721C324E29A8F0092CCFD /* UserDefaultsBacked.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */; }; DA97BB072329902100AAE470 /* LargeSitemap.json in Resources */ = {isa = PBXBuildFile; fileRef = DA97BB062329902000AAE470 /* LargeSitemap.json */; }; DAA42BA821DC97E000244B2A /* NotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA42BA721DC97DF00244B2A /* NotificationTableViewCell.swift */; }; DAA42BAA21DC983B00244B2A /* VideoUITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA42BA921DC983B00244B2A /* VideoUITableViewCell.swift */; }; @@ -399,6 +402,7 @@ DA1C2E6D230DC28F00FACFB0 /* primary_category.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = primary_category.txt; sourceTree = ""; }; DA1C2E6E230DC28F00FACFB0 /* Snapfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Snapfile; sourceTree = ""; }; DA1C32B92311CCE200FACFB0 /* JSONData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONData.swift; sourceTree = ""; }; + DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABServerProperties.swift; sourceTree = ""; }; DA21EAE12339621C001AB415 /* Throttler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Throttler.swift; sourceTree = ""; }; DA28C361225241DE00AB409C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownCaseRepresentable.swift; sourceTree = ""; }; @@ -423,6 +427,7 @@ DA88F8C522EC377100B408E5 /* ReleaseNotes.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = ReleaseNotes.md; sourceTree = ""; }; DA966477232EDEAD00CB418B /* MockURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockURLProtocol.swift; sourceTree = ""; }; DA966479232EE3C200CB418B /* RESTAPITest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTAPITest.swift; sourceTree = ""; }; + DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsBacked.swift; sourceTree = ""; }; DA97BB062329902000AAE470 /* LargeSitemap.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = LargeSitemap.json; sourceTree = ""; }; DAA42BA721DC97DF00244B2A /* NotificationTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationTableViewCell.swift; sourceTree = ""; }; DAA42BA921DC983B00244B2A /* VideoUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoUITableViewCell.swift; sourceTree = ""; }; @@ -680,6 +685,7 @@ 9350F16823814EF500054BA8 /* OpenHABWidget.swift */, 9350F16B23814F0D00054BA8 /* OpenHABWidgetMapping.swift */, DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */, + DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */, ); path = Model; sourceTree = ""; @@ -690,6 +696,7 @@ DA15BFBC23C6726400BD8ADA /* ObservableOpenHABDataObject.swift */, 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */, 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */, + DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */, ); name = Model; path = "openHABWatch Extension/Model"; @@ -1616,6 +1623,7 @@ 9350F16623814ED700054BA8 /* OpenHABSitemapPage.swift in Sources */, 9350F194238151F100054BA8 /* Preferences.swift in Sources */, 93F38C6C238034DA001B1451 /* DataObject.swift in Sources */, + DA1EAECF24E94871008A6B22 /* OpenHABServerProperties.swift in Sources */, 9350F16C23814F0D00054BA8 /* OpenHABWidgetMapping.swift in Sources */, 93F38D4B238037E3001B1451 /* OpenHABAccessTokenAdapter.swift in Sources */, DAB2438C23EF4E1F00C9C68E /* Future.swift in Sources */, @@ -1650,6 +1658,7 @@ 9350F16723814ED700054BA8 /* OpenHABSitemapPage.swift in Sources */, 9350F195238151F100054BA8 /* Preferences.swift in Sources */, 93F38C6D238034DA001B1451 /* DataObject.swift in Sources */, + DA1EAED024E94871008A6B22 /* OpenHABServerProperties.swift in Sources */, 9350F16D23814F0D00054BA8 /* OpenHABWidgetMapping.swift in Sources */, 93F38D4C238037E3001B1451 /* OpenHABAccessTokenAdapter.swift in Sources */, DAE249A223EE07C800986877 /* Future.swift in Sources */, @@ -1697,6 +1706,7 @@ DA07752D2346705F0086C685 /* NotificationController.swift in Sources */, DA0749E023E0BF510057FA83 /* ColorSelection.swift in Sources */, DA65871F236F83CE007E2E7F /* UserDefaultsExtension.swift in Sources */, + DA9721C324E29A8F0092CCFD /* UserDefaultsBacked.swift in Sources */, DA72E1B8236DEA0900B8EF3A /* AppMessageService.swift in Sources */, DA07752B2346705F0086C685 /* ExtensionDelegate.swift in Sources */, DAF4581623DC48400018B495 /* GenericRow.swift in Sources */, diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme index d5b74457a..7b96a84e8 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme @@ -1,6 +1,6 @@ - - - - diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme index 2a63e88c5..5825c9ceb 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme @@ -1,6 +1,6 @@ - - - - diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme index d9e5f7cbc..b8cca27d4 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme @@ -1,6 +1,6 @@ - + notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> + - + - + notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme index 868f13fce..449e47642 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme @@ -1,6 +1,6 @@ - + - + - + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme index 94cf30e66..3bd32af54 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme @@ -1,6 +1,6 @@ - + - + - + - - - - - + diff --git a/openHAB/AppDelegate.swift b/openHAB/AppDelegate.swift index f98fcc2be..cbad6b4f8 100644 --- a/openHAB/AppDelegate.swift +++ b/openHAB/AppDelegate.swift @@ -10,7 +10,7 @@ // SPDX-License-Identifier: EPL-2.0 import AVFoundation -import Firebase +import FirebaseCore import Kingfisher import OpenHABCore import os.log diff --git a/openHAB/GenericUITableViewCell.swift b/openHAB/GenericUITableViewCell.swift index 03414b902..e00492315 100644 --- a/openHAB/GenericUITableViewCell.swift +++ b/openHAB/GenericUITableViewCell.swift @@ -36,8 +36,8 @@ class GenericUITableViewCell: UITableViewCell { // self.userInteractionEnabled = NO; } - customTextLabel?.textColor = _widget.labelcolor != "" ? UIColor(fromString: _widget.labelcolor) : .ohLabel - customDetailTextLabel?.textColor = _widget.valuecolor != "" ? UIColor(fromString: _widget.valuecolor) : .ohSecondaryLabel + customTextLabel?.textColor = !(_widget.labelcolor.isEmpty) ? UIColor(fromString: _widget.labelcolor) : .ohLabel + customDetailTextLabel?.textColor = !(_widget.valuecolor.isEmpty) ? UIColor(fromString: _widget.valuecolor) : .ohSecondaryLabel } } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index ba48dc6a3..d23e59ee6 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -162,7 +162,7 @@ class OpenHABDrawerTableViewController: UITableViewController { let imageView = UIImageView(frame: cell.customImageView.bounds) cell.customTextLabel?.text = sitemaps[indexPath.row].label - if sitemaps[indexPath.row].icon != "" { + if !sitemaps[indexPath.row].icon.isEmpty { 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: "openHABIcon")) diff --git a/openHAB/OpenHABTracker.swift b/openHAB/OpenHABTracker.swift index 4688a2c32..72ee7966e 100644 --- a/openHAB/OpenHABTracker.swift +++ b/openHAB/OpenHABTracker.swift @@ -121,7 +121,7 @@ class OpenHABTracker: NSObject { func trackedRemoteUrl() { let openHABUrl = normalizeUrl(openHABRemoteUrl) - if (openHABUrl?.count ?? 0) > 0 { + if !(openHABUrl ?? "").isEmpty { // delegate?.openHABTrackingProgress("Connecting to remote URL") trackedUrl(URL(string: openHABUrl!)) } else { diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 5d12b31a5..43e1fd41a 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -87,6 +87,7 @@ class OpenHABViewController: UIViewController { var iconType: IconType = .png let search = UISearchController(searchResultsController: nil) var filteredPage: OpenHABSitemapPage? + var serverProperties: OpenHABServerProperties? var relevantPage: OpenHABSitemapPage? { if isFiltering { @@ -265,7 +266,7 @@ class OpenHABViewController: UIViewController { if idleOff { UIApplication.shared.isIdleTimerDisabled = true } - if isViewLoaded, view.window != nil, pageUrl != "" { + if isViewLoaded, view.window != nil, !pageUrl.isEmpty { if !pageNetworkStatusChanged() { os_log("OpenHABViewController isViewLoaded, restarting network activity", log: .viewCycle, type: .info) loadPage(false) @@ -348,7 +349,7 @@ class OpenHABViewController: UIViewController { func doRegisterAps() { let prefsURL = Preferences.remoteUrl if prefsURL.contains("openhab.org") { - if deviceId != "", deviceToken != "", deviceName != "" { + if !deviceId.isEmpty, !deviceToken.isEmpty, !deviceName.isEmpty { 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 { @@ -533,7 +534,7 @@ class OpenHABViewController: UIViewController { self.sitemaps = deriveSitemaps(response.result.value, version: self.appData?.openHABVersion) switch self.sitemaps.count { case 2...: - if self.defaultSitemap != "" { + if !self.defaultSitemap.isEmpty { if let sitemapToOpen = self.sitemap(byName: self.defaultSitemap) { if self.currentPage?.pageId != sitemapToOpen.name { self.currentPage?.widgets.removeAll() // NOTE: remove all widgets to ensure cells get invalidated @@ -641,7 +642,7 @@ class OpenHABViewController: UIViewController { func pageNetworkStatusChanged() -> Bool { os_log("OpenHABViewController pageNetworkStatusChange", log: .remoteAccess, type: .info) - if pageUrl != "" { + if !pageUrl.isEmpty { let pageReachability = NetworkReachabilityManager(host: pageUrl) if !pageNetworkStatusAvailable { pageNetworkStatus = pageReachability?.networkReachabilityStatus @@ -718,10 +719,21 @@ extension OpenHABViewController: OpenHABTrackerDelegate { switch response.result { case .success: os_log("This is an openHAB 2.X", log: .remoteAccess, type: .info) + self.appData?.openHABVersion = 2 + DispatchQueue.main.async { UIApplication.shared.isNetworkActivityIndicatorVisible = false } + + if let data = response.result.value { + do { + self.serverProperties = try data.decoded(as: OpenHABServerProperties.self) + } catch { + os_log("Could not decode JSON response", log: .notifications, type: .error, error.localizedDescription) + } + } + self.selectSitemap() case let .failure(error): os_log("This is an openHAB 1.X", log: .remoteAccess, type: .info) diff --git a/openHAB/SliderUITableViewCell.swift b/openHAB/SliderUITableViewCell.swift index 460dbb41c..43997c797 100644 --- a/openHAB/SliderUITableViewCell.swift +++ b/openHAB/SliderUITableViewCell.swift @@ -15,6 +15,7 @@ import UIKit class SliderUITableViewCell: GenericUITableViewCell { private var isInTransition: Bool = false + private var step: Float = 1.0 private var transitionItem: DispatchWorkItem? private var throttler: Throttler? private var throttlingInterval: TimeInterval? = 0 { @@ -48,6 +49,7 @@ class SliderUITableViewCell: GenericUITableViewCell { selectionStyle = .none separatorInset = .zero throttlingInterval = 0.1 + step = Float(widget.step) } @IBAction private func sliderValueChanged(_ sender: Any) { @@ -80,7 +82,7 @@ class SliderUITableViewCell: GenericUITableViewCell { } private func adj(_ raw: Double) -> Double { - var valueAdjustedToStep = floor((raw - widget.minValue) / widget.step) * widget.step + var valueAdjustedToStep = Double(floor(Float(((raw - widget.minValue))) / step) * step) valueAdjustedToStep += widget.minValue return min(max(valueAdjustedToStep, widget.minValue), widget.maxValue) } @@ -96,21 +98,38 @@ class SliderUITableViewCell: GenericUITableViewCell { override func displayWidget() { guard !isInTransition else { return } - customTextLabel?.text = widget.labelText - widgetSlider?.minimumValue = Float(widget.minValue) - widgetSlider?.maximumValue = Float(widget.maxValue) - let widgetValue = adjustedValue() - widgetSlider?.value = Float(widgetValue) - // if there is a formatted value in widget label, take it. Otherwise display local value - if let labelValue = widget?.labelValue { - customDetailText?.text = labelValue + if let item = widget.item, item.isOfTypeOrGroupType(.color) { + widgetSlider?.minimumValue = 0.0 + widgetSlider?.maximumValue = 100.0 + step = 1.0 + widgetSlider.value = Float(item.state?.parseAsBrightness() ?? 0) } else { - customDetailText?.text = widgetValue.valueText(step: widget.step) + // Fix "The stepSize must be 0, or a factor of the valueFrom-valueTo range" exception + widgetSlider?.minimumValue = Float(widget.minValue) + widgetSlider?.maximumValue = Float(widget.maxValue) + let widgetValue = adjustedValue() + step = Float(widget.step) + + // if there is a formatted value in widget label, take it. Otherwise display local value + if let labelValue = widget?.labelValue { + customDetailText?.text = labelValue + } else { + customDetailText?.text = widgetValue.valueText(step: Double(step)) + } } + customTextLabel?.text = widget.labelText } private func sliderDidChange(toValue value: Double) { os_log("Slider new value = %g", log: .default, type: .info, value) - widget.sendCommand(value.valueText(step: widget.step)) + + if let item = widget.item, item.isOfTypeOrGroupType(.color) { + widget.sendCommand(value.valueText(step: Double(step))) + // connection.httpClient.sendItemCommand(item, value) + } else { + widget.sendCommand(value.valueText(step: Double(step))) + + // connection.httpClient.sendItemUpdate(item, item.state?.asNumber.withValue(value.toFloat())) + } } } diff --git a/openHABCore/Sources/Model/OpenHABServerProperties.swift b/openHABCore/Sources/Model/OpenHABServerProperties.swift new file mode 100644 index 000000000..ba0dc6e61 --- /dev/null +++ b/openHABCore/Sources/Model/OpenHABServerProperties.swift @@ -0,0 +1,35 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +public class OpenHABServerProperties: Decodable { + class OpenHABLink: Decodable { + public var type = "" + public var url = "" + } + + let version: String + let links: [OpenHABLink] + + public var habPanelUrl: String? { + linkUrl(byType: "habpanel") + } + + public func linkUrl(byType type: String?) -> String? { + if let index = links.firstIndex(where: { $0.type == type }) { + return links[index].url + } else { + return nil + } + } + +} diff --git a/openHABCore/Sources/Util/Endpoint.swift b/openHABCore/Sources/Util/Endpoint.swift index 3017be273..924abd7e0 100644 --- a/openHABCore/Sources/Util/Endpoint.swift +++ b/openHABCore/Sources/Util/Endpoint.swift @@ -62,7 +62,7 @@ extension Endpoint { public static func tracker(openHABRootUrl: String) -> Endpoint { Endpoint(baseURL: openHABRootUrl, - path: "/rest/bindings", + path: "/rest", queryItems: []) } diff --git a/openHABCore/Sources/Util/Preferences.swift b/openHABCore/Sources/Util/Preferences.swift index 3bc15c3a4..edf59fb64 100644 --- a/openHABCore/Sources/Util/Preferences.swift +++ b/openHABCore/Sources/Util/Preferences.swift @@ -93,11 +93,4 @@ public struct Preferences { @UserDefault("iconType", defaultValue: 0) public static var iconType: Int @UserDefault("defaultSitemap", defaultValue: "demo") public static var defaultSitemap: String @UserDefault("sendCrashReports", defaultValue: false) public static var sendCrashReports: Bool - - static func readActiveUrl() -> String { - if Preferences.remoteUrl != "" { - return Preferences.remoteUrl - } - return Preferences.localUrl - } } diff --git a/openHABTestsSwift/NumberStateTest.swift b/openHABTestsSwift/NumberStateTest.swift index 58a3b1b22..b49412d77 100644 --- a/openHABTestsSwift/NumberStateTest.swift +++ b/openHABTestsSwift/NumberStateTest.swift @@ -33,6 +33,8 @@ class NumberStateTest: XCTestCase { XCTAssertEqual(NumberState(value: 100.4, unit: "", format: "%.1f %unit%").toString(locale: Locale(identifier: "US")), "100.4 ") XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: nil).toString(locale: Locale(identifier: "US")), "100.4 °C") XCTAssertEqual(NumberState(value: 100.4, unit: nil, format: nil).toString(locale: Locale(identifier: "US")), "100.4") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: "%.1f %unit%").toString(locale: Locale(identifier: "de")), "100,4 °C") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: "%,.1f %unit%").toString(locale: Locale(identifier: "de")), ",.1f °C") // %,.1f is an unvalid format string in Swift } func testToItemType() throws { diff --git a/openHABTestsSwift/OpenHABJSONParserTests.swift b/openHABTestsSwift/OpenHABJSONParserTests.swift index a95cd5062..d2bee0859 100644 --- a/openHABTestsSwift/OpenHABJSONParserTests.swift +++ b/openHABTestsSwift/OpenHABJSONParserTests.swift @@ -529,6 +529,7 @@ class OpenHABJSONParserTests: XCTestCase { } """ let data = Data(json.utf8) + do { var widget: OpenHABWidget widget = try { @@ -544,8 +545,24 @@ class OpenHABJSONParserTests: XCTestCase { } } -// func testUserData() { -// let userData = UserData() -// XCTAssertEqual(userData.items[0].widgetId, "00") -// } + func testServerVersion() { + let json = """ + {"version":"3", "links":[{"type":"uuid","url":"http://192.168.2.15:8081/rest/uuid"}, + {"type":"audio","url":"http://192.168.2.15:8081/rest/audio"},{"type":"bindings","url":"http://192.168.2.15:8081/rest/bindings"},{"type":"channel-types","url":"http://192.168.2.15:8081/rest/channel-types"},{"type":"config-descriptions","url":"http://192.168.2.15:8081/rest/config-descriptions"},{"type":"discovery","url":"http://192.168.2.15:8081/rest/discovery"}, + {"type":"inbox","url":"http://192.168.2.15:8081/rest/inbox"},{"type":"extensions","url":"http://192.168.2.15:8081/rest/extensions"},{"type":"items","url":"http://192.168.2.15:8081/rest/items"},{"type":"links","url":"http://192.168.2.15:8081/rest/links"},{"type":"persistence","url":"http://192.168.2.15:8081/rest/persistence"},{"type":"profile-types","url":"http://192.168.2.15:8081/rest/profile-types"},{"type":"services","url":"http://192.168.2.15:8081/rest/services"}, + {"type":"things","url":"http://192.168.2.15:8081/rest/things"},{"type":"thing-types","url":"http://192.168.2.15:8081/rest/thing-types"},{"type":"sitemaps","url":"http://192.168.2.15:8081/rest/sitemaps"},{"type":"voice","url":"http://192.168.2.15:8081/rest/voice"},{"type":"iconsets","url":"http://192.168.2.15:8081/rest/iconsets"},{"type":"habpanel","url":"http://192.168.2.15:8081/rest/habpanel"}]} + """ + let data = Data(json.utf8) + do { + // var widget: OpenHABServerLinks + let properties = try decoder.decode(OpenHABServerProperties.self, from: data) + + XCTAssertEqual(properties.version, "3", "Checking version") + XCTAssertEqual(properties.links[0].type, "uuid", "Checking finding links") + XCTAssertEqual(properties.linkUrl(byType: "uuid"), "http://192.168.2.15:8081/rest/uuid", "Checking finding link by type") + + } catch { + XCTFail("Whoops, an error occured: \(error)") + } + } } diff --git a/openHABWatch Extension/OpenHABWatchTracker.swift b/openHABWatch Extension/OpenHABWatchTracker.swift index 75f5b4b93..37db8a74f 100644 --- a/openHABWatch Extension/OpenHABWatchTracker.swift +++ b/openHABWatch Extension/OpenHABWatchTracker.swift @@ -40,6 +40,7 @@ class OpenHABWatchTracker: NSObject { } func start() { + #if !os(watchOS) oldReachabilityStatus = pathMonitor.currentPath pathMonitor.pathUpdateHandler = { [weak self] path in guard let self = self else { return } @@ -47,7 +48,7 @@ class OpenHABWatchTracker: NSObject { let nStatus = path if nStatus != self.oldReachabilityStatus { if let oldReachabilityStatus = self.oldReachabilityStatus { - os_log("Network status changed from %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, self.string(from: oldReachabilityStatus) ?? "", self.string(from: nStatus) ?? "") + os_log("Network status changed from %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, oldReachabilityStatus.debugDescription, nStatus.debugDescription) } self.oldReachabilityStatus = nStatus (self.delegate as? OpenHABWatchTrackerExtendedDelegate)?.openHABTrackingNetworkChange(nStatus) @@ -58,7 +59,7 @@ class OpenHABWatchTracker: NSObject { } } pathMonitor.start(queue: backgroundQueue) - + #endif selectUrl() } @@ -67,6 +68,31 @@ class OpenHABWatchTracker: NSObject { } func selectUrl() { + #if os(watchOS) + if ObservableOpenHABDataObject.shared.localUrl.isEmpty { + os_log("Starting discovery", log: .default, type: .debug) + startDiscovery() + } else { + if let connectivityTask = connectivityTask { + connectivityTask.cancel() + } + let request = URLRequest(url: URL(string: ObservableOpenHABDataObject.shared.localUrl)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 2.0) + connectivityTask = NetworkConnection.shared.manager.request(request) + .validate(statusCode: 200 ..< 300) + .responseData { response in + switch response.result { + case .success: + os_log("Tracking local URL", log: .default, type: .debug) + self.trackedLocalUrl() + case .failure: + os_log("Tracking remote URL", log: .default, type: .debug) + self.trackedRemoteUrl() + } + } + connectivityTask?.resume() + } + #else + // Check if any network is available if isNetworkConnected() { // Check if network is WiFi. If not, go for remote URL @@ -103,6 +129,7 @@ class OpenHABWatchTracker: NSObject { let trackingError = NSError(domain: "openHAB", code: 100, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } + #endif } func trackedLocalUrl() { @@ -113,7 +140,7 @@ class OpenHABWatchTracker: NSObject { func trackedRemoteUrl() { let openHABUrl = normalizeUrl(ObservableOpenHABDataObject.shared.remoteUrl) - if (openHABUrl?.count ?? 0) > 0 { + if !(openHABUrl ?? "").isEmpty { // delegate?.openHABTrackingProgress("Connecting to remote URL") trackedUrl(URL(string: openHABUrl!)) } else { @@ -253,14 +280,16 @@ class OpenHABWatchTracker: NSObject { func isNetworkWiFi() -> Bool { (pathMonitor.currentPath.status == .satisfied && !pathMonitor.currentPath.isExpensive) } +} - func string(from path: NWPath) -> String? { - switch path.status { +extension NWPath: CustomStringConvertible { + public var description: String { + switch status { case .unsatisfied, .requiresConnection: return "unreachable" case .satisfied: var str = "reachable:" - for interface in path.availableInterfaces { + for interface in availableInterfaces { switch interface.type { case .wifi: str += " wifi" diff --git a/openHABWatch Extension/PreferencesHostingController.swift b/openHABWatch Extension/PreferencesHostingController.swift index f6566ce2c..5356e5b7b 100644 --- a/openHABWatch Extension/PreferencesHostingController.swift +++ b/openHABWatch Extension/PreferencesHostingController.swift @@ -9,6 +9,7 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCoreWatch import SwiftUI import WatchKit diff --git a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift index c609f8fd5..ba3142b89 100644 --- a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift +++ b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift @@ -34,7 +34,8 @@ struct PreferencesSwiftUIView: View { PreferencesRowUIView(label: "Sitemap", content: settings.sitemapName).font(.footnote) PreferencesRowUIView(label: "Username", content: settings.openHABUsername).font(.footnote) HStack { - Button(action: { AppMessageService.singleton.requestApplicationContext() }, label: { Text("Sync preferences") }) + Button(action: { AppMessageService.singleton.requestApplicationContext() + }, label: { Text("Sync preferences") }) } } } diff --git a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift index c133443ae..1c1cf7980 100644 --- a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift @@ -20,7 +20,7 @@ struct DetailTextLabelView: View { Text($0) .font(.footnote) .lineLimit(1) - .foregroundColor(self.widget.valuecolor != "" ? Color(fromString: self.widget.valuecolor) : .secondary) + .foregroundColor(!self.widget.valuecolor.isEmpty ? Color(fromString: self.widget.valuecolor) : .secondary) } } } diff --git a/openHABWatch Extension/Views/Utils/TextLabelView.swift b/openHABWatch Extension/Views/Utils/TextLabelView.swift index 4b46c44f8..98cbd02b5 100644 --- a/openHABWatch Extension/Views/Utils/TextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/TextLabelView.swift @@ -19,7 +19,7 @@ struct TextLabelView: View { Text(widget.labelText ?? "") .font(.caption) .lineLimit(2) - .foregroundColor(widget.labelcolor != "" ? Color(fromString: widget.labelcolor) : .primary) + .foregroundColor(!widget.labelcolor.isEmpty ? Color(fromString: widget.labelcolor) : .primary) } } diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift index 3b233a688..248982906 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift @@ -13,28 +13,6 @@ import Combine import Foundation import OpenHABCoreWatch -@propertyWrapper -struct UserDefault { - let key: String - let defaultValue: T - // https://www.swiftbysundell.com/articles/property-wrappers-in-swift/ - var storage: UserDefaults = .standard - - public var wrappedValue: T { - get { - storage.object(forKey: key) as? T ?? defaultValue - } - set { - storage.set(newValue, forKey: key) - } - } - - init(_ key: String, defaultValue: T) { - self.key = key - self.defaultValue = defaultValue - } -} - final class ObservableOpenHABDataObject: DataObject, ObservableObject { static let shared = ObservableOpenHABDataObject() @@ -43,49 +21,49 @@ final class ObservableOpenHABDataObject: DataObject, ObservableObject { let objectWillChange = PassthroughSubject() let objectRefreshed = PassthroughSubject() - @UserDefault("rootUrl", defaultValue: "") + @UserDefaultsBacked(key: "rootUrl", defaultValue: "") var openHABRootUrl: String { willSet { objectWillChange.send() } } - @UserDefault("localUrl", defaultValue: "") + @UserDefaultsBacked(key: "localUrl", defaultValue: "") var localUrl: String { willSet { objectWillChange.send() } } - @UserDefault("remoteUrl", defaultValue: "") + @UserDefaultsBacked(key: "remoteUrl", defaultValue: "") var remoteUrl: String { willSet { objectWillChange.send() } } - @UserDefault("sitemapName", defaultValue: "") + @UserDefaultsBacked(key: "sitemapName", defaultValue: "") var sitemapName: String { willSet { objectWillChange.send() } } - @UserDefault("username", defaultValue: "") + @UserDefaultsBacked(key: "username", defaultValue: "") var openHABUsername: String { willSet { objectWillChange.send() } } - @UserDefault("password", defaultValue: "") + @UserDefaultsBacked(key: "password", defaultValue: "") var openHABPassword: String { willSet { objectWillChange.send() } } - @UserDefault("ignoreSSL", defaultValue: true) + @UserDefaultsBacked(key: "ignoreSSL", defaultValue: true) var ignoreSSL: Bool { willSet { objectWillChange.send() @@ -93,14 +71,14 @@ final class ObservableOpenHABDataObject: DataObject, ObservableObject { } } - @UserDefault("alwaysSendCreds", defaultValue: false) + @UserDefaultsBacked(key: "alwaysSendCreds", defaultValue: false) var openHABAlwaysSendCreds: Bool { willSet { objectWillChange.send() } } - @UserDefault("haveReceivedAppContext", defaultValue: false) + @UserDefaultsBacked(key: "haveReceivedAppContext", defaultValue: false) var haveReceivedAppContext: Bool { didSet { objectRefreshed.send() diff --git a/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift b/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift new file mode 100644 index 000000000..fa0de07a4 --- /dev/null +++ b/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift @@ -0,0 +1,36 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +@propertyWrapper +struct UserDefaultsBacked { + let key: String + let defaultValue: T + // https://www.swiftbysundell.com/articles/property-wrappers-in-swift/ + var storage: UserDefaults = .standard + + public var wrappedValue: T { + get { + storage.object(forKey: key) as? T ?? defaultValue + } + set { + storage.set(newValue, forKey: key) + } + } +} + +/// Convenience initializer when UserDefaults is optional. +extension UserDefaultsBacked where T: ExpressibleByNilLiteral { + init(key: String, storage: UserDefaults = .standard) { + self.init(key: key, defaultValue: nil, storage: storage) + } +} diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 9cdb2d41a..691c0a81d 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -97,14 +97,6 @@ final class UserData: ObservableObject { refreshUrl() } - func loadPage(urlString: String, - longPolling: Bool, - refresh: Bool, - sitemapName: String = "watch") { - let url = Endpoint.watchSitemap(openHABRootUrl: urlString, sitemapName: sitemapName).url - loadPage(url: url, longPolling: longPolling, refresh: refresh) - } - func request(_ endpoint: Endpoint) -> OpenHABCoreWatch.Future { // Start by constructing a Promise, that will later be // returned as a Future @@ -142,20 +134,6 @@ final class UserData: ObservableObject { return promise } - func loadPage(_ endpoint: Endpoint) { - request(endpoint) - .decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - .trafo() - .observe { result in - switch result { - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@", log: .remoteAccess, type: .error, error.localizedDescription) - case let .success(page): - self.openHABSitemapPage = page - } - } - } - func loadPage(url: URL?, longPolling: Bool, refresh: Bool) { @@ -226,6 +204,20 @@ final class UserData: ObservableObject { tracker?.selectUrl() } } + + func loadPage(_ endpoint: Endpoint) { + request(endpoint) + .decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + .trafo() + .observe { result in + switch result { + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@", log: .remoteAccess, type: .error, error.localizedDescription) + case let .success(page): + self.openHABSitemapPage = page + } + } + } } extension UserData: OpenHABWatchTrackerDelegate { @@ -241,10 +233,9 @@ extension UserData: OpenHABWatchTrackerDelegate { } ObservableOpenHABDataObject.shared.openHABRootUrl = urlString - loadPage(urlString: urlString, - longPolling: false, - refresh: true, - sitemapName: ObservableOpenHABDataObject.shared.sitemapName) + + let url = Endpoint.watchSitemap(openHABRootUrl: urlString, sitemapName: ObservableOpenHABDataObject.shared.sitemapName).url + loadPage(url: url, longPolling: false, refresh: true) } func openHABTrackingProgress(_ message: String?) { From 4ab27a07fc675c141a8d85ebc4d92541ee4b87f0 Mon Sep 17 00:00:00 2001 From: weak Date: Thu, 20 Aug 2020 16:47:52 +0200 Subject: [PATCH 16/78] fix valueToText(:) --- openHABCore/Sources/Util/DoubleExtension.swift | 1 + openHABTestsSwift/OpenHABGeneralTests.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openHABCore/Sources/Util/DoubleExtension.swift b/openHABCore/Sources/Util/DoubleExtension.swift index 7c8beeac6..3281de089 100644 --- a/openHABCore/Sources/Util/DoubleExtension.swift +++ b/openHABCore/Sources/Util/DoubleExtension.swift @@ -15,6 +15,7 @@ extension Double { public func valueText(step: Double) -> String { let digits = max(-Decimal(step).exponent, 0) let numberFormatter = NumberFormatter() + numberFormatter.minimumFractionDigits = digits numberFormatter.maximumFractionDigits = digits numberFormatter.decimalSeparator = "." return numberFormatter.string(from: NSNumber(value: self)) ?? "" diff --git a/openHABTestsSwift/OpenHABGeneralTests.swift b/openHABTestsSwift/OpenHABGeneralTests.swift index 283551f47..781ef60a4 100644 --- a/openHABTestsSwift/OpenHABGeneralTests.swift +++ b/openHABTestsSwift/OpenHABGeneralTests.swift @@ -29,7 +29,7 @@ class OpenHABGeneralTests: XCTestCase { return String(format: "%.\(digits)f", widgetValue) } - XCTAssertEqual(1000.0.valueText(step: 5.23), "1000.00") + XCTAssertEqual(1000.0.valueText(step: 0.01), "1000.00") XCTAssertEqual(1000.0.valueText(step: 1), "1000") XCTAssertEqual(valueTextWithoutFormatter(1000.0, step: 5.23), "1000.00") } From 54132ffe5d8e2723f69282af40e6238753886cc5 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Thu, 20 Aug 2020 17:43:58 +0200 Subject: [PATCH 17/78] Create swift.yml --- .github/workflows/swift.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/swift.yml diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml new file mode 100644 index 000000000..a5153d755 --- /dev/null +++ b/.github/workflows/swift.yml @@ -0,0 +1,19 @@ +name: Swift + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +jobs: + build: + + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + - name: Build + run: swift build -v + - name: Run tests + run: swift test -v From 03e8e0a8278cafbb075d4454317ee2499f400d59 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Thu, 20 Aug 2020 17:54:04 +0200 Subject: [PATCH 18/78] Update swift.yml --- .github/workflows/swift.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index a5153d755..35e8fa616 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -13,7 +13,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Build - run: swift build -v - - name: Run tests - run: swift test -v + - name: Build app + run: | + fastlane run build_app(scheme: "openHAB", clean: true, export_method: "app-store") +#- name: Build +# run: swift build -v +# - name: Run tests +# run: swift test -v From 1e0b00fb7b938c27f77b6b5c2cac4a051b3e5d41 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Thu, 20 Aug 2020 17:56:39 +0200 Subject: [PATCH 19/78] Update swift.yml --- .github/workflows/swift.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 35e8fa616..1011471ea 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - name: Build app run: | - fastlane run build_app(scheme: "openHAB", clean: true, export_method: "app-store") + fastlane run build_app (scheme: "openHAB", clean: true, export_method: "app-store") #- name: Build # run: swift build -v # - name: Run tests From ae095a57f3bfeff24cab384f1658dc238ecdddb2 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Fri, 21 Aug 2020 14:07:03 +0200 Subject: [PATCH 20/78] Update swift.yml --- .github/workflows/swift.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 1011471ea..878fac99e 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -13,9 +13,13 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Build app - run: | - fastlane run build_app (scheme: "openHAB", clean: true, export_method: "app-store") + # - name: Build app + # run: | + # fastlane run build_app (scheme: "openHAB", clean: true, export_method: "app-store") + + - name: Start xcodebuild test + run: xcodebuild -showBuildSettings -workspace ./openHAB.xcworkspace -scheme openHAB + # run: xcodebuild clean test -project TodoSampleApp.xcodeproj -scheme TodoSampleApp -destination "platform=iOS Simulator,name=iPhone 11 Pro" #- name: Build # run: swift build -v # - name: Run tests From 6f737102a9beb490cad9494bea5e5444455a755b Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sat, 22 Aug 2020 20:29:39 +0200 Subject: [PATCH 21/78] Update and rename swift.yml to publish.yml input from @weakfl --- .github/workflows/publish.yml | 54 +++++++++++++++++++++++++++++++++++ .github/workflows/swift.yml | 26 ----------------- 2 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/swift.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..2e08896b0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,54 @@ +name: Publish on TestFlight + +on: [push] + +jobs: + publish_app: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache cocoapods dependencies + uses: actions/cache@v2 + env: + cache-name: cache-cocoapods-dependencies + with: + path: /Pods + key: ${{ runner.os }}-pods-${{ env.cache-name }}-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods-${{ env.cache-name }}- + + - name: Setup Cocoapods + uses: maxim-lobanov/setup-cocoapods@v1.1 + with: + podfile-path: /Podfile.lock + + - name: Install Dependencies + run: | + cd + pod install --repo-update + shell: bash + + - name: SSH Config + run: echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config + + - name: SSH Keys + uses: webfactory/ssh-agent@v0.4.0 + with: + ssh-private-key: | + ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + ${{ secrets.GIT_PRIVATE_KEY }} + + - name: fastlane iOS beta + env: + FASTLANE_USER: ${{ secrets.FASTLANE_USER }} + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }} + uses: maierj/fastlane-action@v1.4.0 + with: + lane: beta + subdirectory: + skip-tracking: true diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml deleted file mode 100644 index 878fac99e..000000000 --- a/.github/workflows/swift.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Swift - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - build: - - runs-on: macos-latest - - steps: - - uses: actions/checkout@v2 - # - name: Build app - # run: | - # fastlane run build_app (scheme: "openHAB", clean: true, export_method: "app-store") - - - name: Start xcodebuild test - run: xcodebuild -showBuildSettings -workspace ./openHAB.xcworkspace -scheme openHAB - # run: xcodebuild clean test -project TodoSampleApp.xcodeproj -scheme TodoSampleApp -destination "platform=iOS Simulator,name=iPhone 11 Pro" -#- name: Build -# run: swift build -v -# - name: Run tests -# run: swift test -v From 7fb9ab8ac0d1a93540cc683106d6c6a4095704ac Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 23 Aug 2020 09:29:40 +0200 Subject: [PATCH 22/78] update github workflow --- .github/workflows/publish.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2e08896b0..f1013d4bd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,6 +1,8 @@ name: Publish on TestFlight -on: [push] +on: + push: + branches: [develop] jobs: publish_app: @@ -14,7 +16,7 @@ jobs: env: cache-name: cache-cocoapods-dependencies with: - path: /Pods + path: Pods key: ${{ runner.os }}-pods-${{ env.cache-name }}-${{ hashFiles('**/Podfile.lock') }} restore-keys: | ${{ runner.os }}-pods-${{ env.cache-name }}- @@ -22,11 +24,17 @@ jobs: - name: Setup Cocoapods uses: maxim-lobanov/setup-cocoapods@v1.1 with: - podfile-path: /Podfile.lock + podfile-path: Podfile.lock + + - name: Check Pods existence + id: check_files + uses: andstor/file-existence-action@v1 + with: + files: "Pods" - name: Install Dependencies + if: steps.check_files.outputs.files_exists == 'false' run: | - cd pod install --repo-update shell: bash @@ -43,12 +51,13 @@ jobs: - name: fastlane iOS beta env: FASTLANE_USER: ${{ secrets.FASTLANE_USER }} - FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }} + LANG: en_US.UTF-8 + LC_ALL: en_US.UTF-8 uses: maierj/fastlane-action@v1.4.0 with: lane: beta - subdirectory: skip-tracking: true From f8d0185dbe091499c3cd97451e23975d114ce704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 23 Aug 2020 15:54:14 +0200 Subject: [PATCH 23/78] minimumFractionDigits only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHABCore/Sources/Util/DoubleExtension.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/openHABCore/Sources/Util/DoubleExtension.swift b/openHABCore/Sources/Util/DoubleExtension.swift index 4098b3b1a..3281de089 100644 --- a/openHABCore/Sources/Util/DoubleExtension.swift +++ b/openHABCore/Sources/Util/DoubleExtension.swift @@ -17,7 +17,6 @@ extension Double { let numberFormatter = NumberFormatter() numberFormatter.minimumFractionDigits = digits numberFormatter.maximumFractionDigits = digits - numberFormatter.minimumFractionDigits = digits numberFormatter.decimalSeparator = "." return numberFormatter.string(from: NSNumber(value: self)) ?? "" } From 637f45118e390fd4be8added9f51a13ee1052536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 23 Aug 2020 20:03:15 +0200 Subject: [PATCH 24/78] Preparing release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Gemfile.lock | 16 ++++++++-------- openHAB.xcodeproj/project.pbxproj | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3ba21ab31..3d43f501c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,8 +6,8 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.349.0) - aws-sdk-core (3.104.3) + aws-partitions (1.358.0) + aws-sdk-core (3.104.4) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) @@ -15,11 +15,11 @@ GEM aws-sdk-kms (1.36.0) aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.75.0) - aws-sdk-core (~> 3, >= 3.104.1) + aws-sdk-s3 (1.78.0) + aws-sdk-core (~> 3, >= 3.104.3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.2.1) + aws-sigv4 (1.2.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.3) claide (1.0.3) @@ -44,7 +44,7 @@ GEM faraday_middleware (1.0.0) faraday (~> 1.0) fastimage (2.2.0) - fastlane (2.154.0) + fastlane (2.156.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) @@ -117,7 +117,7 @@ GEM httpclient (2.8.3) jmespath (1.4.0) json (2.3.1) - jwt (2.2.1) + jwt (2.2.2) memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) @@ -159,7 +159,7 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.17.1) + xcodeproj (1.18.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 3297a64d1..43160ef04 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1872,7 +1872,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1916,7 +1916,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1957,7 +1957,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2005,7 +2005,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2053,7 +2053,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2103,7 +2103,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2151,7 +2151,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; @@ -2190,7 +2190,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; @@ -2226,7 +2226,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2268,7 +2268,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2310,7 +2310,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2355,7 +2355,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2508,7 +2508,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2555,7 +2555,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410447; + CURRENT_PROJECT_VERSION = 1580410448; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; From ddf7e8fe11d64d42c4c16601acddcbbd2157f8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 23 Aug 2020 20:03:57 +0200 Subject: [PATCH 25/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 43160ef04..5d66a3aaf 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1872,7 +1872,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1884,7 +1884,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1916,7 +1916,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1928,7 +1928,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1957,7 +1957,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -1976,7 +1976,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2005,7 +2005,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2053,7 +2053,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2071,7 +2071,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2103,7 +2103,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2120,7 +2120,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2151,14 +2151,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2190,14 +2190,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2226,7 +2226,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2238,7 +2238,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2268,7 +2268,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2280,7 +2280,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2310,7 +2310,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2322,7 +2322,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2355,7 +2355,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2367,7 +2367,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2508,7 +2508,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2525,7 +2525,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2555,7 +2555,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410448; + CURRENT_PROJECT_VERSION = 1580410449; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2572,7 +2572,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.27; + MARKETING_VERSION = 2.3.28; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From f09377da9a8e2e2ada7f3a4dfffacd050be234a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 23 Aug 2020 20:22:16 +0200 Subject: [PATCH 26/78] Changing version number to 2.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB.xcodeproj/project.pbxproj | 20 ++++++++++---------- openHAB/openHAB-Info.plist | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 5d66a3aaf..0c38da4b1 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1976,7 +1976,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2071,7 +2071,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2120,7 +2120,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2158,7 +2158,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2197,7 +2197,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2238,7 +2238,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2280,7 +2280,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2525,7 +2525,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2572,7 +2572,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.0; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; diff --git a/openHAB/openHAB-Info.plist b/openHAB/openHAB-Info.plist index 07039ec38..e38b45929 100644 --- a/openHAB/openHAB-Info.plist +++ b/openHAB/openHAB-Info.plist @@ -2,8 +2,6 @@ - firebase_crashlytics_collection_enabled - CFBundleDevelopmentRegion en CFBundleDisplayName @@ -112,5 +110,7 @@ + firebase_crashlytics_collection_enabled + From 1d3beb91a6b54f4b232c1362b758d16fede18eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 23 Aug 2020 20:23:30 +0200 Subject: [PATCH 27/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 0c38da4b1..032f34dd8 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1872,7 +1872,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1884,7 +1884,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1916,7 +1916,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1928,7 +1928,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1957,7 +1957,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -1976,7 +1976,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2005,7 +2005,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2053,7 +2053,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2071,7 +2071,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2103,7 +2103,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2120,7 +2120,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2151,14 +2151,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2190,14 +2190,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2226,7 +2226,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2238,7 +2238,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2268,7 +2268,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2280,7 +2280,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2310,7 +2310,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2322,7 +2322,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2355,7 +2355,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2367,7 +2367,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.28; + MARKETING_VERSION = 2.4.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2508,7 +2508,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2525,7 +2525,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2555,7 +2555,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410449; + CURRENT_PROJECT_VERSION = 1580410450; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2572,7 +2572,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From 6e840c0783b991977ad2329e1d9003afd93704a0 Mon Sep 17 00:00:00 2001 From: weakfl Date: Sun, 23 Aug 2020 22:00:13 +0200 Subject: [PATCH 28/78] Develop l10n (#563) * add initial l10ns and unit tests Signed-off-by: weak * add additional languages Signed-off-by: weak * add crowdin lane and prepare github workflow integration Signed-off-by: weak * rename crowdin config file for fastlane to avoid possible naming conflicts Signed-off-by: weak --- .github/workflows/publish.yml | 3 + Gemfile.lock | 87 +++--- fastlane/Fastfile | 268 +++++++++++------- openHAB.xcodeproj/project.pbxproj | 165 +++++++++-- .../xcshareddata/xcschemes/openHAB.xcscheme | 3 +- openHAB/AppDelegate.swift | 6 +- openHAB/{Base.lproj => }/Main.storyboard | 102 ++++++- openHAB/OpenHABSettingsViewController.swift | 9 + openHAB/OpenHABTracker.swift | 12 +- openHAB/OpenHABViewController.swift | 70 ++--- openHAB/Resources/crowdinfiles.yml | 43 +++ .../cs.lproj}/InfoPlist.strings | 0 .../Resources/cs.lproj/Localizable.strings | 58 ++++ openHAB/Resources/da.lproj/InfoPlist.strings | 2 + .../Resources/da.lproj/Localizable.strings | 58 ++++ openHAB/Resources/de.lproj/InfoPlist.strings | 2 + .../Resources/de.lproj/Localizable.strings | 58 ++++ openHAB/Resources/el.lproj/InfoPlist.strings | 2 + .../Resources/el.lproj/Localizable.strings | 58 ++++ openHAB/Resources/en.lproj/InfoPlist.strings | 2 + .../Resources/en.lproj/Localizable.strings | 58 ++++ openHAB/Resources/es.lproj/InfoPlist.strings | 2 + .../Resources/es.lproj/Localizable.strings | 58 ++++ openHAB/Resources/fi.lproj/InfoPlist.strings | 2 + .../Resources/fi.lproj/Localizable.strings | 58 ++++ openHAB/Resources/fr.lproj/InfoPlist.strings | 2 + .../Resources/fr.lproj/Localizable.strings | 58 ++++ openHAB/Resources/hu.lproj/InfoPlist.strings | 2 + .../Resources/hu.lproj/Localizable.strings | 58 ++++ openHAB/Resources/it.lproj/InfoPlist.strings | 2 + .../Resources/it.lproj/Localizable.strings | 58 ++++ openHAB/Resources/nb.lproj/InfoPlist.strings | 2 + .../Resources/nb.lproj/Localizable.strings | 58 ++++ openHAB/Resources/nl.lproj/InfoPlist.strings | 2 + .../Resources/nl.lproj/Localizable.strings | 58 ++++ openHAB/Resources/pl.lproj/InfoPlist.strings | 2 + .../Resources/pl.lproj/Localizable.strings | 58 ++++ .../Resources/pt-BR.lproj/InfoPlist.strings | 2 + .../Resources/pt-BR.lproj/Localizable.strings | 58 ++++ .../Resources/pt-PT.lproj/InfoPlist.strings | 2 + .../Resources/pt-PT.lproj/Localizable.strings | 58 ++++ openHAB/Resources/ro.lproj/InfoPlist.strings | 2 + .../Resources/ro.lproj/Localizable.strings | 58 ++++ openHAB/Resources/ru.lproj/InfoPlist.strings | 2 + .../Resources/ru.lproj/Localizable.strings | 58 ++++ openHAB/Resources/sr.lproj/InfoPlist.strings | 2 + .../Resources/sr.lproj/Localizable.strings | 58 ++++ .../Resources/sv-SE.lproj/InfoPlist.strings | 2 + .../Resources/sv-SE.lproj/Localizable.strings | 58 ++++ openHAB/Resources/tr.lproj/InfoPlist.strings | 2 + .../Resources/tr.lproj/Localizable.strings | 58 ++++ openHAB/Resources/uk.lproj/InfoPlist.strings | 2 + .../Resources/uk.lproj/Localizable.strings | 58 ++++ openHAB/UILabel+Localization.swift | 24 ++ openHAB/UIViewController+Localization.swift | 24 ++ .../Util/ClientCertificateManager.swift | 6 +- openHABTestsSwift/LocalizationTests.swift | 150 ++++++++++ .../ExtensionDelegate.swift | 4 +- .../OpenHABWatchTracker.swift | 12 +- .../Views/ContentView.swift | 12 +- .../Views/PreferencesSwiftUIView.swift | 14 +- .../openHABWatch Extension/UserData.swift | 2 +- openHABWatch/it.lproj/Interface.strings | 3 + 63 files changed, 2026 insertions(+), 251 deletions(-) rename openHAB/{Base.lproj => }/Main.storyboard (95%) create mode 100644 openHAB/Resources/crowdinfiles.yml rename openHAB/{en.lproj => Resources/cs.lproj}/InfoPlist.strings (100%) create mode 100644 openHAB/Resources/cs.lproj/Localizable.strings create mode 100644 openHAB/Resources/da.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/da.lproj/Localizable.strings create mode 100644 openHAB/Resources/de.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/de.lproj/Localizable.strings create mode 100644 openHAB/Resources/el.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/el.lproj/Localizable.strings create mode 100644 openHAB/Resources/en.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/en.lproj/Localizable.strings create mode 100644 openHAB/Resources/es.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/es.lproj/Localizable.strings create mode 100644 openHAB/Resources/fi.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/fi.lproj/Localizable.strings create mode 100644 openHAB/Resources/fr.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/fr.lproj/Localizable.strings create mode 100644 openHAB/Resources/hu.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/hu.lproj/Localizable.strings create mode 100644 openHAB/Resources/it.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/it.lproj/Localizable.strings create mode 100644 openHAB/Resources/nb.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/nb.lproj/Localizable.strings create mode 100644 openHAB/Resources/nl.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/nl.lproj/Localizable.strings create mode 100644 openHAB/Resources/pl.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/pl.lproj/Localizable.strings create mode 100644 openHAB/Resources/pt-BR.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/pt-BR.lproj/Localizable.strings create mode 100644 openHAB/Resources/pt-PT.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/pt-PT.lproj/Localizable.strings create mode 100644 openHAB/Resources/ro.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/ro.lproj/Localizable.strings create mode 100644 openHAB/Resources/ru.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/ru.lproj/Localizable.strings create mode 100644 openHAB/Resources/sr.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/sr.lproj/Localizable.strings create mode 100644 openHAB/Resources/sv-SE.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/sv-SE.lproj/Localizable.strings create mode 100644 openHAB/Resources/tr.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/tr.lproj/Localizable.strings create mode 100644 openHAB/Resources/uk.lproj/InfoPlist.strings create mode 100644 openHAB/Resources/uk.lproj/Localizable.strings create mode 100644 openHAB/UILabel+Localization.swift create mode 100644 openHAB/UIViewController+Localization.swift create mode 100644 openHABTestsSwift/LocalizationTests.swift create mode 100644 openHABWatch/it.lproj/Interface.strings diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f1013d4bd..560e54989 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -55,6 +55,9 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }} + OH_CROWDIN_PROJECT_ID: ${{ secrets.OH_CROWDIN_PROJECT_ID }} + OH_CROWDIN_USERNAME: ${{ secrets.OH_CROWDIN_USERNAME }} + OH_CROWDIN_ACCOUNT_KEY: ${{ secrets.OH_CROWDIN_ACCOUNT_KEY }} LANG: en_US.UTF-8 LC_ALL: en_US.UTF-8 uses: maierj/fastlane-action@v1.4.0 diff --git a/Gemfile.lock b/Gemfile.lock index 789de1756..62e1e79f3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,70 +6,69 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.304.0) - aws-sdk-core (3.94.0) + aws-partitions (1.358.0) + aws-sdk-core (3.104.4) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.30.0) - aws-sdk-core (~> 3, >= 3.71.0) + aws-sdk-kms (1.36.0) + aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.63.0) - aws-sdk-core (~> 3, >= 3.83.0) + aws-sdk-s3 (1.78.0) + aws-sdk-core (~> 3, >= 3.104.3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.3) - aws-eventstream (~> 1.0, >= 1.0.2) + aws-sigv4 (1.2.2) + aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.3) claide (1.0.3) colored (1.2) colored2 (3.1.2) commander-fastlane (4.4.6) highline (~> 1.7.2) - declarative (0.0.10) + declarative (0.0.20) declarative-option (0.1.0) - digest-crc (0.5.1) + digest-crc (0.6.1) + rake (~> 13.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) - emoji_regex (1.0.1) - excon (0.73.0) - faraday (0.17.3) + dotenv (2.7.6) + emoji_regex (3.0.0) + excon (0.76.0) + faraday (1.0.1) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) faraday (>= 0.7.4) http-cookie (~> 1.0.0) - faraday_middleware (0.13.1) - faraday (>= 0.7.4, < 1.0) - fastimage (2.1.7) - fastlane (2.146.1) + faraday_middleware (1.0.0) + faraday (~> 1.0) + fastimage (2.2.0) + fastlane (2.156.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.2, < 2.0.0) + babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored commander-fastlane (>= 4.4.6, < 5.0.0) dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 2.0) + emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) - faraday (~> 0.17) + faraday (~> 1.0) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.13.1) + faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.29.2, < 0.37.0) + google-api-client (>= 0.37.0, < 0.39.0) google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) - jwt (~> 2.1.0) + jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) - multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) - public_suffix (~> 2.0.0) - rubyzip (>= 1.3.0, < 2.0.0) + rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) @@ -84,7 +83,7 @@ GEM fastlane-plugin-changelog (0.15.0) fastlane-plugin-versioning (0.4.3) gh_inspector (1.1.3) - google-api-client (0.36.4) + google-api-client (0.38.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) @@ -95,17 +94,17 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.1) + google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.0.0) - google-cloud-storage (1.26.0) + google-cloud-errors (1.0.1) + google-cloud-storage (1.27.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.12.0) + googleauth (0.13.1) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -117,26 +116,26 @@ GEM domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.4.0) - json (2.3.0) - jwt (2.1.0) + json (2.3.1) + jwt (2.2.2) memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) - multi_json (1.14.1) - multi_xml (0.6.0) + multi_json (1.15.0) multipart-post (2.0.0) - nanaimo (0.2.6) + nanaimo (0.3.0) naturally (2.2.0) - os (1.1.0) + os (1.1.1) plist (3.5.0) - public_suffix (2.0.5) + public_suffix (4.0.5) + rake (13.0.1) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) retriable (3.1.2) rouge (2.0.7) - rubyzip (1.3.0) + rubyzip (2.3.0) security (0.1.3) signet (0.14.0) addressable (~> 2.3) @@ -151,7 +150,7 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) tty-cursor (0.7.1) - tty-screen (0.7.1) + tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) @@ -160,12 +159,12 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.16.0) + xcodeproj (1.18.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.6) + nanaimo (~> 0.3.0) xcpretty (0.3.0) rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.0) @@ -180,4 +179,4 @@ DEPENDENCIES fastlane-plugin-versioning BUNDLED WITH - 2.0.2 + 2.1.4 diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 13d3239bc..4c52e24b1 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -16,115 +16,167 @@ default_platform(:ios) platform :ios do - desc "Generate new localized screenshots" - lane :screenshots do - capture_screenshots(workspace: "openHAB.xcworkspace", - scheme: "openHABUITests", - dark_mode: true) - end - - desc 'Run unit tests.' - lane :unittests do - run_tests( - workspace: 'openHAB.xcworkspace', - scheme: 'openHABTestsSwift', - devices: ['iPhone 11 Pro'] - ) - end - - desc 'Refresh dSYMS.' - lane :refresh_dsyms do - download_dsyms( - version: "latest", - wait_for_dsym_processing: true, - wait_timeout: 600) - upload_symbols_to_crashlytics - clean_build_artifacts - end - - desc "Build beta" - lane :beta do |lane| - - # check the semantic parameter entered - if !lane[:bump] - raise "No bump type defined! Use one of: patch | minor | major".red + desc 'Generate new localized screenshots' + lane :screenshots do + capture_screenshots(workspace: 'openHAB.xcworkspace', + scheme: 'openHABUITests', + dark_mode: true) end - ensure_git_branch( - branch: "(master|develop|release\\S+|hotfix\\S+)" - ) - - # ensure that master branch is clean - ensure_git_status_clean - - # run unit tests - #unittests - - increment_build_number_in_xcodeproj( - xcodeproj: "openHAB.xcodeproj" - ) - - type = lane[:bump] - - increment_version_number_in_xcodeproj( - bump_type: type, - xcodeproj: "openHAB.xcodeproj" - ) - - build_number = get_build_number - version = get_version_number(xcodeproj: "openHAB.xcodeproj", - target: "openHAB") - - # get the last commit comments from Git history - # and creates our changelog - comments = changelog_from_git_commits( - between: [last_git_tag, "HEAD"], - pretty: "- %s", - date_format: "short", - match_lightweight_tag: false, - merge_commit_filtering: "exclude_merges" - ) - - changelog = read_changelog # Read changelog - - stamp_changelog(section_identifier: "Version #{version}, Build #{build_number}") # Stamp Unreleased section with newly released build number - - clean_build_artifacts - - # commit to git the changes from bumping version number - commit_version_bump(message: "Committed version bump", - xcodeproj: "openHAB.xcodeproj", - force: true) - - # push bump commit - push_to_git_remote - - # create a local tag with the new version - add_git_tag( - message: changelog, - tag: "#{version}") - - # publish a new release into Github - github_release = set_github_release( - api_token: ENV["GITHUB_TOKEN"], - repository_name: "openhab/openhab-ios", - name: "#{type.capitalize} version #{version}", - tag_name: "#{version}", - description: changelog, - commitish: "master" - # upload_assets: no assets supported - ) - build_app(scheme: "openHAB", - clean: true, - export_method: "app-store") - upload_to_testflight( - distribute_external: true, - notify_external_testers: true, - changelog: changelog, - groups: ["Beta Testers"] - ) - refresh_dsyms - - end + desc 'Run unit tests.' + lane :unittests do + run_tests( + workspace: 'openHAB.xcworkspace', + scheme: 'openHABTestsSwift', + devices: ['iPhone 11 Pro'] + ) + end + + desc 'Refresh dSYMS.' + lane :refresh_dsyms do + download_dsyms( + version: 'latest', + wait_for_dsym_processing: true, + wait_timeout: 600 + ) + upload_symbols_to_crashlytics + clean_build_artifacts + end + + desc 'Build beta' + lane :beta do |lane| + # check the semantic parameter entered + raise 'No bump type defined! Use one of: patch | minor | major'.red unless lane[:bump] + + ensure_git_branch( + branch: '(master|develop|release\\S+|hotfix\\S+)' + ) + + # ensure that master branch is clean + ensure_git_status_clean + + # update L10ns + crowdin + + # run unit tests + unittests + + increment_build_number_in_xcodeproj( + xcodeproj: 'openHAB.xcodeproj' + ) + + type = lane[:bump] + + increment_version_number_in_xcodeproj( + bump_type: type, + xcodeproj: 'openHAB.xcodeproj' + ) + + build_number = get_build_number + version = get_version_number(xcodeproj: 'openHAB.xcodeproj', + target: 'openHAB') + + # get the last commit comments from Git history + # and creates our changelog + comments = changelog_from_git_commits( + between: [last_git_tag, 'HEAD'], + pretty: '- %s', + date_format: 'short', + match_lightweight_tag: false, + merge_commit_filtering: 'exclude_merges' + ) + + changelog = read_changelog # Read changelog + + stamp_changelog(section_identifier: "Version #{version}, Build #{build_number}") # Stamp Unreleased section with newly released build number + + clean_build_artifacts + + git_add(path: "./openHAB/Resources/*/*.strings", shell_escape: false) + # commit to git the changes from bumping version number + commit_version_bump(message: 'Committed version bump', + xcodeproj: 'openHAB.xcodeproj', + force: true) + + # push bump commit + ensure_git_status_clean + push_to_git_remote + + # create a local tag with the new version + add_git_tag( + message: changelog, + tag: version.to_s + ) + + # publish a new release into Github + github_release = set_github_release( + api_token: ENV['GITHUB_TOKEN'], + repository_name: 'openhab/openhab-ios', + name: "#{type.capitalize} version #{version}", + tag_name: version.to_s, + description: changelog, + commitish: 'master' + # upload_assets: no assets supported + ) + build_app(scheme: 'openHAB', + clean: true, + export_method: 'app-store') + upload_to_testflight( + distribute_external: true, + notify_external_testers: true, + changelog: changelog, + groups: ['Beta Testers'] + ) + refresh_dsyms + end + + # This currently only updates Localizable.strings + # Regions.strings and InfoPlist.strings must be done manually + desc 'Download strings files from Crowdin' + lane :crowdin do + if ENV['OH_CROWDIN_PROJECT_ID'] != nil && ENV['OH_CROWDIN_USERNAME'] != nil && ENV['OH_CROWDIN_ACCOUNT_KEY'] != nil + unless File.exist?(File.expand_path('..') + '/openHAB/Resources/crowdinfiles.yml') + UI.user_error!("crowdinfile.yml is required to run this lane! Aborted \u{1F6D1}") + end + config = YAML.load(File.read(File.expand_path('..') + '/openHAB/Resources/crowdinfiles.yml')) + build = "https://api.crowdin.com/api/project/#{ENV["OH_CROWDIN_PROJECT_ID"]}/export?login=#{ENV["OH_CROWDIN_USERNAME"]}&account-key=#{ENV["OH_CROWDIN_ACCOUNT_KEY"]}" + dl = "https://api.crowdin.com/api/project/#{ENV["OH_CROWDIN_PROJECT_ID"]}/download/all.zip?login=#{ENV["OH_CROWDIN_USERNAME"]}&account-key=#{ENV["OH_CROWDIN_ACCOUNT_KEY"]}" + path = File.expand_path('..') + '/openHAB/Resources/' + langs = config['langs'] + # Expected size of the array, used to check if new languages have been added or not + # The size logic can be omitted if needed + size = 42 + + response = Net::HTTP.get_response(URI(build)) + if response.is_a? Net::HTTPSuccess + puts "Strings project built! \u{1F57A}" + puts 'Downloading zip file....' + content = open(dl) + puts 'Updating files....' + Zip::File.open_buffer(content) do |zip| + # The size logic can be omitted if needed + unless zip.entries.count == size + UI.user_error!("Additional languages have been added, please reconfigure yml file!! \u{1F6D1}") + end + zip.each do |entry| + next unless langs.key?(entry.name) + + # Key found, pull content and write to file + langs[entry.name].each do |lang| + content = entry.get_input_stream.read + full_path = path + lang + '/Localizable.strings' + puts "Updated! \u{1F4AA} " + full_path + File.open(full_path, 'w') { |file| file.write(content) } + end + end + puts "String update complete! \u{1F984}" + end + else + UI.user_error!("Failed to build project strings \u{1F622}") + end + else + UI.important 'Missing credentials, skipping crowdin download.' + end + end end diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 37f3cc4c2..96ec3aa1c 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -57,6 +57,14 @@ 9350F195238151F100054BA8 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9350F193238151F100054BA8 /* Preferences.swift */; }; 9350F1972381523700054BA8 /* Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9350F1962381523700054BA8 /* Equatable.swift */; }; 9350F1982381523700054BA8 /* Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9350F1962381523700054BA8 /* Equatable.swift */; }; + 938BF89624EFBC5400E6B52F /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 938BF89524EFBC5400E6B52F /* LocalizationTests.swift */; }; + 938BF9C424EFCB9F00E6B52F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 938BF9C324EFCB9F00E6B52F /* Main.storyboard */; }; + 938BF9C624EFCC0700E6B52F /* UILabel+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 938BF9C524EFCC0700E6B52F /* UILabel+Localization.swift */; }; + 938BF9D024EFCCC000E6B52F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 938BF9C824EFCCC000E6B52F /* Localizable.strings */; }; + 938BF9D124EFCCC000E6B52F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 938BF9CA24EFCCC000E6B52F /* InfoPlist.strings */; }; + 938BF9D324EFD0B700E6B52F /* UIViewController+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 938BF9D224EFD0B700E6B52F /* UIViewController+Localization.swift */; }; + 938BF9D424EFD5B100E6B52F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 938BF9C824EFCCC000E6B52F /* Localizable.strings */; }; + 938BF9D524EFD5B100E6B52F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 938BF9C824EFCCC000E6B52F /* Localizable.strings */; }; 938EDCE122C4FEB800661CA1 /* ScaleAspectFitImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 938EDCE022C4FEB800661CA1 /* ScaleAspectFitImageView.swift */; }; 93F38C4723803499001B1451 /* OpenHABCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F38C4523803499001B1451 /* OpenHABCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; 93F38C4A23803499001B1451 /* OpenHABCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93F38C4323803499001B1451 /* OpenHABCore.framework */; }; @@ -72,7 +80,6 @@ 93F38D4C238037E3001B1451 /* OpenHABAccessTokenAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93F38D4A238037E3001B1451 /* OpenHABAccessTokenAdapter.swift */; }; A07ED02E2402EE6E006588FE /* OpenHABWatchTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07ED02D2402EE6E006588FE /* OpenHABWatchTracker.swift */; }; A07EF7A02230C0A30040919F /* OpenHABClientCertificatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07EF79F2230C0A20040919F /* OpenHABClientCertificatesViewController.swift */; }; - A3F4C3A31A49A5090019A09F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A3F4C3A11A49A5090019A09F /* Main.storyboard */; }; A3F4C3A51A49A5940019A09F /* MainLaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = A3F4C3A41A49A5940019A09F /* MainLaunchScreen.xib */; }; B7D5ECE121499E55001B0EC6 /* MapViewTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7D5ECE021499E55001B0EC6 /* MapViewTableViewCell.swift */; }; DA0749DE23E0B5950057FA83 /* ColorPickerRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0749DD23E0B5950057FA83 /* ColorPickerRow.swift */; }; @@ -166,7 +173,6 @@ DFB2622B18830A3600D3244D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFB2622A18830A3600D3244D /* Foundation.framework */; }; DFB2622D18830A3600D3244D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFB2622C18830A3600D3244D /* CoreGraphics.framework */; }; DFB2622F18830A3600D3244D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFB2622E18830A3600D3244D /* UIKit.framework */; }; - DFB2623518830A3600D3244D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DFB2623318830A3600D3244D /* InfoPlist.strings */; }; DFB2623B18830A3600D3244D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB2623A18830A3600D3244D /* AppDelegate.swift */; }; DFB2624418830A3600D3244D /* OpenHABViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB2624318830A3600D3244D /* OpenHABViewController.swift */; }; DFB2624618830A3600D3244D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DFB2624518830A3600D3244D /* Images.xcassets */; }; @@ -289,6 +295,42 @@ 656916D81FCB82BC00667B2A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "openHAB/GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; 77B765C78F4B9EB6A989362C /* Pods_openHABWatch_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_openHABWatch_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8F0E24B8CEAD77483918122F /* Pods-OpenHABCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenHABCore.debug.xcconfig"; path = "Target Support Files/Pods-OpenHABCore/Pods-OpenHABCore.debug.xcconfig"; sourceTree = ""; }; + 931384B324F259BC00A73AB5 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + 931384B424F259BD00A73AB5 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384B524F2688300A73AB5 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; + 931384B624F2688300A73AB5 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384B724F268DB00A73AB5 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; + 931384B824F268DB00A73AB5 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384B924F268EA00A73AB5 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; }; + 931384BA24F268EB00A73AB5 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384BB24F2691B00A73AB5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; + 931384BC24F2691B00A73AB5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384BD24F2693700A73AB5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 931384BE24F2693800A73AB5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384BF24F2695B00A73AB5 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = ""; }; + 931384C024F2695B00A73AB5 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384C124F2697200A73AB5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 931384C224F2697200A73AB5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384C324F2698A00A73AB5 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 931384C424F2698A00A73AB5 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384C524F269B000A73AB5 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 931384C624F269B000A73AB5 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384C724F269C500A73AB5 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = ""; }; + 931384C824F269C600A73AB5 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = ""; }; + 931384C924F269CB00A73AB5 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; }; + 931384CA24F269CB00A73AB5 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; + 931384CB24F269FC00A73AB5 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; + 931384CC24F269FC00A73AB5 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384CD24F26A4200A73AB5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 931384CE24F26A4200A73AB5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384CF24F26A8300A73AB5 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = ""; }; + 931384D024F26A8300A73AB5 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384D124F26ACD00A73AB5 /* sv-SE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sv-SE"; path = "sv-SE.lproj/Localizable.strings"; sourceTree = ""; }; + 931384D224F26ACD00A73AB5 /* sv-SE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sv-SE"; path = "sv-SE.lproj/InfoPlist.strings"; sourceTree = ""; }; + 931384D324F26AEA00A73AB5 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; + 931384D424F26AEA00A73AB5 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; + 931384D524F26AFD00A73AB5 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = ""; }; + 931384D624F26AFD00A73AB5 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = ""; }; 933D7F0422E7015000621A03 /* openHABUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = openHABUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 933D7F0622E7015000621A03 /* OpenHABUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABUITests.swift; sourceTree = ""; }; 933D7F0822E7015100621A03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -315,6 +357,16 @@ 9350F190238151CE00054BA8 /* StringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; }; 9350F193238151F100054BA8 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 9350F1962381523700054BA8 /* Equatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Equatable.swift; sourceTree = ""; }; + 938BF89524EFBC5400E6B52F /* LocalizationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationTests.swift; sourceTree = ""; }; + 938BF9C324EFCB9F00E6B52F /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + 938BF9C524EFCC0700E6B52F /* UILabel+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Localization.swift"; sourceTree = ""; }; + 938BF9C924EFCCC000E6B52F /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 938BF9CB24EFCCC000E6B52F /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 938BF9CC24EFCCC000E6B52F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 938BF9CD24EFCCC000E6B52F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 938BF9CE24EFCCC000E6B52F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 938BF9CF24EFCCC000E6B52F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 938BF9D224EFD0B700E6B52F /* UIViewController+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Localization.swift"; sourceTree = ""; }; 938EDCE022C4FEB800661CA1 /* ScaleAspectFitImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScaleAspectFitImageView.swift; sourceTree = ""; }; 9394102522CB5CDB00EB4255 /* Collection+SafeAccess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+SafeAccess.swift"; sourceTree = ""; }; 93F38C4323803499001B1451 /* OpenHABCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenHABCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -329,7 +381,6 @@ 93F38D4A238037E3001B1451 /* OpenHABAccessTokenAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenHABAccessTokenAdapter.swift; sourceTree = ""; }; A07ED02D2402EE6E006588FE /* OpenHABWatchTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenHABWatchTracker.swift; path = "openHABWatch Extension/OpenHABWatchTracker.swift"; sourceTree = SOURCE_ROOT; }; A07EF79F2230C0A20040919F /* OpenHABClientCertificatesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenHABClientCertificatesViewController.swift; sourceTree = ""; }; - A3F4C3A21A49A5090019A09F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = openHAB/Base.lproj/Main.storyboard; sourceTree = ""; }; A3F4C3A41A49A5940019A09F /* MainLaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = MainLaunchScreen.xib; path = ../MainLaunchScreen.xib; sourceTree = ""; }; A4286216545D31B234012400 /* Pods-openHABUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-openHABUITests.debug.xcconfig"; path = "Target Support Files/Pods-openHABUITests/Pods-openHABUITests.debug.xcconfig"; sourceTree = ""; }; A4C4C3B393913405F231E759 /* Pods-openHABTestsSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-openHABTestsSwift.release.xcconfig"; path = "Target Support Files/Pods-openHABTestsSwift/Pods-openHABTestsSwift.release.xcconfig"; sourceTree = ""; }; @@ -467,7 +518,6 @@ DFB2622C18830A3600D3244D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; DFB2622E18830A3600D3244D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; DFB2623218830A3600D3244D /* openHAB-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "openHAB-Info.plist"; sourceTree = ""; }; - DFB2623418830A3600D3244D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; DFB2623A18830A3600D3244D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; DFB2624318830A3600D3244D /* OpenHABViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABViewController.swift; sourceTree = ""; }; DFB2624518830A3600D3244D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; @@ -618,6 +668,15 @@ path = openHABUITests; sourceTree = ""; }; + 938BF9C724EFCCC000E6B52F /* Resources */ = { + isa = PBXGroup; + children = ( + 938BF9C824EFCCC000E6B52F /* Localizable.strings */, + 938BF9CA24EFCCC000E6B52F /* InfoPlist.strings */, + ); + path = Resources; + sourceTree = ""; + }; 93F38C4423803499001B1451 /* OpenHABCore */ = { isa = PBXGroup; children = ( @@ -807,6 +866,7 @@ DA966479232EE3C200CB418B /* RESTAPITest.swift */, DA19E25A22FD801D002F8F2F /* OpenHABGeneralTests.swift */, DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */, + 938BF89524EFBC5400E6B52F /* LocalizationTests.swift */, DA97BB062329902000AAE470 /* LargeSitemap.json */, DA1C32B92311CCE200FACFB0 /* JSONData.swift */, DAB9C7B0230B323000A7DB6E /* OpenHABXMLParserTests.swift */, @@ -994,7 +1054,7 @@ DFB2623018830A3600D3244D /* openHAB */ = { isa = PBXGroup; children = ( - A3F4C3A11A49A5090019A09F /* Main.storyboard */, + 938BF9C324EFCB9F00E6B52F /* Main.storyboard */, A3F4C3A41A49A5940019A09F /* MainLaunchScreen.xib */, DFB2623A18830A3600D3244D /* AppDelegate.swift */, DFDEE3FE1883228C008B26AC /* Models */, @@ -1003,6 +1063,7 @@ DFDEE3FF18832293008B26AC /* Util */, 1224F78B228A89E300750965 /* Watch */, DFB2623118830A3600D3244D /* Supporting Files */, + 938BF9C724EFCCC000E6B52F /* Resources */, ); path = openHAB; sourceTree = ""; @@ -1013,7 +1074,6 @@ DA88F8C522EC377100B408E5 /* ReleaseNotes.md */, 653C09D41EAD691A00BA4C4A /* openHAB.entitlements */, 656916D81FCB82BC00667B2A /* GoogleService-Info.plist */, - DFB2623318830A3600D3244D /* InfoPlist.strings */, DFDF45301932042B00A6E581 /* legal.rtf */, DFB2623218830A3600D3244D /* openHAB-Info.plist */, DFDA3CE9193CADB200888039 /* ping.wav */, @@ -1045,6 +1105,8 @@ DFFD8FD018EDBD4F003B502A /* UICircleButton.swift */, 286F556E22EA062700AECC5C /* DynamicButtonStyleBell.swift */, 286F557022EA3D4E00AECC5C /* DynamicButtonStyleGear.swift */, + 938BF9C524EFCC0700E6B52F /* UILabel+Localization.swift */, + 938BF9D224EFD0B700E6B52F /* UIViewController+Localization.swift */, ); name = Util; sourceTree = ""; @@ -1278,6 +1340,26 @@ knownRegions = ( en, Base, + de, + it, + es, + cs, + da, + el, + fi, + fr, + hu, + nl, + nb, + pl, + "pt-PT", + "pt-BR", + ro, + ru, + sr, + "sv-SE", + tr, + uk, ); mainGroup = DFB2621E18830A3600D3244D; productRefGroup = DFB2622818830A3600D3244D /* Products */; @@ -1322,6 +1404,7 @@ buildActionMask = 2147483647; files = ( DA07751B2346705F0086C685 /* Assets.xcassets in Resources */, + 938BF9D424EFD5B100E6B52F /* Localizable.strings in Resources */, DA0775192346705D0086C685 /* Interface.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1331,6 +1414,7 @@ buildActionMask = 2147483647; files = ( 932602EE2382892B00EAD685 /* Assets.xcassets in Resources */, + 938BF9D524EFD5B100E6B52F /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1347,13 +1431,14 @@ buildActionMask = 2147483647; files = ( DF4B84071885AE0E00F34902 /* blankicon.png in Resources */, + 938BF9D024EFCCC000E6B52F /* Localizable.strings in Resources */, DFB2624618830A3600D3244D /* Images.xcassets in Resources */, + 938BF9D124EFCCC000E6B52F /* InfoPlist.strings in Resources */, + 938BF9C424EFCB9F00E6B52F /* Main.storyboard in Resources */, DA817E7A234BF39B00C91824 /* CHANGELOG.md in Resources */, DA4D4DB5233F9ACB00B37E37 /* README.md in Resources */, - DFB2623518830A3600D3244D /* InfoPlist.strings in Resources */, DA88F8C622EC377200B408E5 /* ReleaseNotes.md in Resources */, DFDF45311932042B00A6E581 /* legal.rtf in Resources */, - A3F4C3A31A49A5090019A09F /* Main.storyboard in Resources */, 656916D91FCB82BC00667B2A /* GoogleService-Info.plist in Resources */, A3F4C3A51A49A5940019A09F /* MainLaunchScreen.xib in Resources */, DFDA3CEA193CADB200888039 /* ping.wav in Resources */, @@ -1709,6 +1794,7 @@ DAB9C7B1230B323000A7DB6E /* OpenHABXMLParserTests.swift in Sources */, DA19E25B22FD801D002F8F2F /* OpenHABGeneralTests.swift in Sources */, DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */, + 938BF89624EFBC5400E6B52F /* LocalizationTests.swift in Sources */, DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */, DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */, DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */, @@ -1741,6 +1827,7 @@ DAF4F6C0222734D300C24876 /* NewImageUITableViewCell.swift in Sources */, DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */, DF1B302D1CF5C667009C921C /* OpenHABNotification.swift in Sources */, + 938BF9D324EFD0B700E6B52F /* UIViewController+Localization.swift in Sources */, DF06F1F618FE7A160011E7B9 /* OpenHABSelectionTableViewController.swift in Sources */, DAA42BA821DC97E000244B2A /* NotificationTableViewCell.swift in Sources */, 286F556F22EA062700AECC5C /* DynamicButtonStyleBell.swift in Sources */, @@ -1758,6 +1845,7 @@ DFA13CB418872EBD006355C3 /* SwitchUITableViewCell.swift in Sources */, DFFD8FD118EDBD4F003B502A /* UICircleButton.swift in Sources */, A07EF7A02230C0A30040919F /* OpenHABClientCertificatesViewController.swift in Sources */, + 938BF9C624EFCC0700E6B52F /* UILabel+Localization.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1797,29 +1885,68 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - A3F4C3A11A49A5090019A09F /* Main.storyboard */ = { + 938BF9C824EFCCC000E6B52F /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( - A3F4C3A21A49A5090019A09F /* Base */, - ); - name = Main.storyboard; - path = ..; + 938BF9C924EFCCC000E6B52F /* de */, + 938BF9CC24EFCCC000E6B52F /* en */, + 938BF9CE24EFCCC000E6B52F /* it */, + 931384B324F259BC00A73AB5 /* es */, + 931384B524F2688300A73AB5 /* cs */, + 931384B724F268DB00A73AB5 /* da */, + 931384B924F268EA00A73AB5 /* el */, + 931384BB24F2691B00A73AB5 /* fi */, + 931384BD24F2693700A73AB5 /* fr */, + 931384BF24F2695B00A73AB5 /* hu */, + 931384C124F2697200A73AB5 /* nl */, + 931384C324F2698A00A73AB5 /* nb */, + 931384C524F269B000A73AB5 /* pl */, + 931384C724F269C500A73AB5 /* pt-PT */, + 931384C924F269CB00A73AB5 /* pt-BR */, + 931384CB24F269FC00A73AB5 /* ro */, + 931384CD24F26A4200A73AB5 /* ru */, + 931384CF24F26A8300A73AB5 /* sr */, + 931384D124F26ACD00A73AB5 /* sv-SE */, + 931384D324F26AEA00A73AB5 /* tr */, + 931384D524F26AFD00A73AB5 /* uk */, + ); + name = Localizable.strings; sourceTree = ""; }; - DA0775172346705D0086C685 /* Interface.storyboard */ = { + 938BF9CA24EFCCC000E6B52F /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( - DA0775182346705D0086C685 /* Base */, + 938BF9CB24EFCCC000E6B52F /* de */, + 938BF9CD24EFCCC000E6B52F /* en */, + 938BF9CF24EFCCC000E6B52F /* it */, + 931384B424F259BD00A73AB5 /* es */, + 931384B624F2688300A73AB5 /* cs */, + 931384B824F268DB00A73AB5 /* da */, + 931384BA24F268EB00A73AB5 /* el */, + 931384BC24F2691B00A73AB5 /* fi */, + 931384BE24F2693800A73AB5 /* fr */, + 931384C024F2695B00A73AB5 /* hu */, + 931384C224F2697200A73AB5 /* nl */, + 931384C424F2698A00A73AB5 /* nb */, + 931384C624F269B000A73AB5 /* pl */, + 931384C824F269C600A73AB5 /* pt-PT */, + 931384CA24F269CB00A73AB5 /* pt-BR */, + 931384CC24F269FC00A73AB5 /* ro */, + 931384CE24F26A4200A73AB5 /* ru */, + 931384D024F26A8300A73AB5 /* sr */, + 931384D224F26ACD00A73AB5 /* sv-SE */, + 931384D424F26AEA00A73AB5 /* tr */, + 931384D624F26AFD00A73AB5 /* uk */, ); - name = Interface.storyboard; + name = InfoPlist.strings; sourceTree = ""; }; - DFB2623318830A3600D3244D /* InfoPlist.strings */ = { + DA0775172346705D0086C685 /* Interface.storyboard */ = { isa = PBXVariantGroup; children = ( - DFB2623418830A3600D3244D /* en */, + DA0775182346705D0086C685 /* Base */, ); - name = InfoPlist.strings; + name = Interface.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme index d5b74457a..5552383e5 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme @@ -68,7 +68,8 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES"> + allowLocationSimulation = "YES" + showNonLocalizedStrings = "YES"> - + - + @@ -590,9 +590,13 @@ + + + + @@ -623,9 +627,13 @@ + + + - + + @@ -658,9 +666,13 @@ + + + - + + @@ -675,6 +687,7 @@ + @@ -693,9 +706,13 @@ + + + - + + @@ -728,9 +745,13 @@ + + + + @@ -763,9 +784,13 @@ + + + + @@ -800,9 +825,13 @@ + + + + @@ -815,6 +844,7 @@ + @@ -833,6 +863,9 @@ + + + @@ -854,11 +887,13 @@ - + @@ -871,8 +906,9 @@ - + + @@ -889,12 +925,15 @@ + @@ -906,7 +945,7 @@ - + @@ -926,6 +965,9 @@ + + + @@ -946,6 +988,9 @@ + + + @@ -975,6 +1020,9 @@ + + + @@ -1000,6 +1048,9 @@ + + + @@ -1021,12 +1072,15 @@ + @@ -1038,7 +1092,7 @@ - + @@ -1058,6 +1112,9 @@ + + + @@ -1206,6 +1263,9 @@ + + + + + + diff --git a/openHAB/OpenHABSettingsViewController.swift b/openHAB/OpenHABSettingsViewController.swift index 990d3d1cf..50cbcc4ba 100644 --- a/openHAB/OpenHABSettingsViewController.swift +++ b/openHAB/OpenHABSettingsViewController.swift @@ -134,6 +134,15 @@ class OpenHABSettingsViewController: UITableViewController, UITextFieldDelegate } } + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch section { + case 0: + return NSLocalizedString("openhab_connection", comment: "") + default: + return NSLocalizedString("application_settings", comment: "") + } + } + func enableConnectionSettings() { settingsTableView.reloadData() } diff --git a/openHAB/OpenHABTracker.swift b/openHAB/OpenHABTracker.swift index 4688a2c32..ee3c20f1f 100644 --- a/openHAB/OpenHABTracker.swift +++ b/openHAB/OpenHABTracker.swift @@ -107,14 +107,14 @@ class OpenHABTracker: NSObject { } } else { var errorDetail: [AnyHashable: Any] = [:] - errorDetail[NSLocalizedDescriptionKey] = "Network is not available." + errorDetail[NSLocalizedDescriptionKey] = NSLocalizedString("network_not_available", comment: "") let trackingError = NSError(domain: "openHAB", code: 100, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } } func trackedLocalUrl() { - delegate?.openHABTrackingProgress("Connecting to local URL") + delegate?.openHABTrackingProgress(NSLocalizedString("connecting_local", comment: "")) let openHABUrl = normalizeUrl(openHABLocalUrl) trackedUrl(URL(string: openHABUrl!)) } @@ -126,19 +126,19 @@ class OpenHABTracker: NSObject { trackedUrl(URL(string: openHABUrl!)) } else { var errorDetail: [AnyHashable: Any] = [:] - errorDetail[NSLocalizedDescriptionKey] = "Remote URL is not configured." + errorDetail[NSLocalizedDescriptionKey] = NSLocalizedString("remote_url_not_configured", comment: "") let trackingError = NSError(domain: "openHAB", code: 101, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } } func trackedDiscoveryUrl(_ discoveryUrl: URL?) { - delegate?.openHABTrackingProgress("Connecting to discovered URL") + delegate?.openHABTrackingProgress(NSLocalizedString("connecting_discovered", comment: "")) trackedUrl(discoveryUrl) } func trackedDemoMode() { - delegate?.openHABTrackingProgress("Running in demo mode. Check settings to disable demo mode.") + delegate?.openHABTrackingProgress(NSLocalizedString("running_demo_mode", comment: "")) trackedUrl(URL(staticString: "http://demo.openhab.org:8080")) } @@ -149,7 +149,7 @@ class OpenHABTracker: NSObject { func startDiscovery() { os_log("OpenHABTracking starting Bonjour discovery", log: .default, type: .info) - delegate?.openHABTrackingProgress("Discovering openHAB") + delegate?.openHABTrackingProgress(NSLocalizedString("discovering_oh", comment: "")) netService = NetService(domain: "local.", type: "_openhab-server-ssl._tcp.", name: "openHAB-ssl") netService!.delegate = self netService!.resolve(withTimeout: 5.0) diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index a924a3933..c0782ac07 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -158,7 +158,7 @@ class OpenHABViewController: UIViewController { search.searchResultsUpdater = self search.obscuresBackgroundDuringPresentation = false - search.searchBar.placeholder = "Search openHAB items" + search.searchBar.placeholder = NSLocalizedString("search_items", comment: "") definesPresentationContext = true setupSideMenu() @@ -494,8 +494,8 @@ class OpenHABViewController: UIViewController { let view = MessageView.viewFromNib(layout: .cardView) // ... configure the view view.configureTheme(.error) - view.configureContent(title: "Error", body: "SSL Certificate Error") - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -509,8 +509,8 @@ class OpenHABViewController: UIViewController { let view = MessageView.viewFromNib(layout: .cardView) // ... configure the view view.configureTheme(.error) - view.configureContent(title: "Error", body: error.localizedDescription) - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -559,8 +559,8 @@ class OpenHABViewController: UIViewController { let view = MessageView.viewFromNib(layout: .cardView) // ... configure the view view.configureTheme(.error) - view.configureContent(title: "Error", body: "openHAB returned empty sitemap list") - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("empty_sitemap", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -582,8 +582,8 @@ class OpenHABViewController: UIViewController { UIApplication.shared.isNetworkActivityIndicatorVisible = false let view = MessageView.viewFromNib(layout: .cardView) view.configureTheme(.error) - view.configureContent(title: "Error", body: "SSL Certificate Error") - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -596,8 +596,8 @@ class OpenHABViewController: UIViewController { UIApplication.shared.isNetworkActivityIndicatorVisible = false let view = MessageView.viewFromNib(layout: .cardView) view.configureTheme(.error) - view.configureContent(title: "Error", body: error.localizedDescription) - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -746,8 +746,8 @@ extension OpenHABViewController: OpenHABTrackerDelegate { UIApplication.shared.isNetworkActivityIndicatorVisible = false let view = MessageView.viewFromNib(layout: .cardView) view.configureTheme(.info) - view.configureContent(title: "Connecting", body: message ?? "") - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("connecting", comment: ""), body: message ?? "") + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -764,8 +764,8 @@ extension OpenHABViewController: OpenHABTrackerDelegate { let view = MessageView.viewFromNib(layout: .cardView) // ... configure the view view.configureTheme(.error) - view.configureContent(title: "Error", body: error.localizedDescription) - view.button?.setTitle("Dismiss", for: .normal) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) view.buttonTapHandler = { _ in SwiftMessages.hide() } return view } @@ -813,10 +813,12 @@ 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: "Always", style: .default) { _ in policy?.evaluateResult = .permitAlways }) + let title = NSLocalizedString("ssl_certificate_warning", comment: "") + let message = String(format: NSLocalizedString("ssl_certificate_invalid", comment: ""), certificateSummary ?? "", domain ?? "") + let alertView = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: NSLocalizedString("abort", comment: ""), style: .default) { _ in policy?.evaluateResult = .deny }) + alertView.addAction(UIAlertAction(title: NSLocalizedString("once", comment: ""), style: .default) { _ in policy?.evaluateResult = .permitOnce }) + alertView.addAction(UIAlertAction(title: NSLocalizedString("always", comment: ""), style: .default) { _ in policy?.evaluateResult = .permitAlways }) self.present(alertView, animated: true) {} } } @@ -824,10 +826,12 @@ extension OpenHABViewController: ServerCertificateManagerDelegate { // certificate received from openHAB doesn't match our record, ask user for a decision 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: "Always", style: .default) { _ in policy?.evaluateResult = .permitAlways }) + let title = NSLocalizedString("ssl_certificate_warning", comment: "") + let message = String(format: NSLocalizedString("ssl_certificate_no_match", comment: ""), certificateSummary ?? "", domain ?? "") + let alertView = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: NSLocalizedString("abort", comment: ""), style: .default) { _ in policy?.evaluateResult = .deny }) + alertView.addAction(UIAlertAction(title: NSLocalizedString("once", comment: ""), style: .default) { _ in policy?.evaluateResult = .permitOnce }) + alertView.addAction(UIAlertAction(title: NSLocalizedString("always", comment: ""), style: .default) { _ in policy?.evaluateResult = .permitAlways }) self.present(alertView, animated: true) {} } } @@ -844,11 +848,11 @@ 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 { - let alertController = UIAlertController(title: "Client Certificate Import", message: "Import client certificate into the keychain?", preferredStyle: .alert) - let okay = UIAlertAction(title: "Okay", style: .default) { (_: UIAlertAction) in + let alertController = UIAlertController(title: NSLocalizedString("certificate_import_title", comment: ""), message: NSLocalizedString("certificate_import_text", comment: ""), preferredStyle: .alert) + let okay = UIAlertAction(title: NSLocalizedString("okay", comment: ""), style: .default) { (_: UIAlertAction) in clientCertificateManager!.clientCertificateAccepted(password: nil) } - let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (_: UIAlertAction) in + let cancel = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), style: .cancel) { (_: UIAlertAction) in clientCertificateManager!.clientCertificateRejected() } alertController.addAction(okay) @@ -860,17 +864,17 @@ extension OpenHABViewController: ClientCertificateManagerDelegate { // delegate should ask user for the export password used to decode the PKCS#12 func askForCertificatePassword(_ clientCertificateManager: ClientCertificateManager?) { DispatchQueue.main.async { - let alertController = UIAlertController(title: "Client Certificate Import", message: "Password required for import.", preferredStyle: .alert) - let okay = UIAlertAction(title: "Okay", style: .default) { (_: UIAlertAction) in + let alertController = UIAlertController(title: NSLocalizedString("certificate_import_title", comment: ""), message: NSLocalizedString("certificate_import_password", comment: ""), preferredStyle: .alert) + let okay = UIAlertAction(title: NSLocalizedString("okay", comment: ""), style: .default) { (_: UIAlertAction) in let txtField = alertController.textFields?.first let password = txtField?.text clientCertificateManager!.clientCertificateAccepted(password: password) } - let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (_: UIAlertAction) in + let cancel = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), style: .cancel) { (_: UIAlertAction) in clientCertificateManager!.clientCertificateRejected() } alertController.addTextField { textField in - textField.placeholder = "Password" + textField.placeholder = NSLocalizedString("password", comment: "") textField.isSecureTextEntry = true } alertController.addAction(okay) @@ -882,8 +886,8 @@ extension OpenHABViewController: ClientCertificateManagerDelegate { // delegate should alert the user that an error occured importing the certificate func alertClientCertificateError(_ clientCertificateManager: ClientCertificateManager?, errMsg: String) { DispatchQueue.main.async { - let alertController = UIAlertController(title: "Client Certificate Import", message: errMsg, preferredStyle: .alert) - let okay = UIAlertAction(title: "Okay", style: .default) + let alertController = UIAlertController(title: NSLocalizedString("certificate_import_title", comment: ""), message: errMsg, preferredStyle: .alert) + let okay = UIAlertAction(title: NSLocalizedString("okay", comment: ""), style: .default) alertController.addAction(okay) self.present(alertController, animated: true, completion: nil) } @@ -1141,7 +1145,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { if let cell = tableView.cellForRow(at: indexPath) as? GenericUITableViewCell, cell.widget.type == "Text", let text = cell.widget?.labelValue ?? cell.widget?.labelText, !text.isEmpty { return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in - let copy = UIAction(title: "Copy item label", image: UIImage(systemName: "square.and.arrow.up")) { _ in + let copy = UIAction(title: NSLocalizedString("copy_label", comment: ""), image: UIImage(systemName: "square.and.arrow.up")) { _ in UIPasteboard.general.string = text } diff --git a/openHAB/Resources/crowdinfiles.yml b/openHAB/Resources/crowdinfiles.yml new file mode 100644 index 000000000..c7479d2b8 --- /dev/null +++ b/openHAB/Resources/crowdinfiles.yml @@ -0,0 +1,43 @@ +langs: + en/Localizable.strings: + - en.lproj + de/Localizable.strings: + - de.lproj + es-ES/Localizable.strings: + - es.lproj + it/Localizable.strings: + - it.lproj + cs/Localizable.strings: + - cs.lproj + da/Localizable.strings: + - da.lproj + el/Localizable.strings: + - el.lproj + fi/Localizable.strings: + - fi.lproj + fr/Localizable.strings: + - fr.lproj + hu/Localizable.strings: + - hu.lproj + nl/Localizable.strings: + - nl.lproj + no/Localizable.strings: + - nb.lproj + pl/Localizable.strings: + - pl.lproj + pt-PT/Localizable.strings: + - pt-PT.lproj + pt-BR/Localizable.strings: + - pt-BR.lproj + ro/Localizable.strings: + - ro.lproj + ru/Localizable.strings: + - ru.lproj + sr/Localizable.strings: + - sr.lproj + sv-SE/Localizable.strings: + - sv-SE.lproj + tr/Localizable.strings: + - tr.lproj + uk/Localizable.strings: + - uk.lproj diff --git a/openHAB/en.lproj/InfoPlist.strings b/openHAB/Resources/cs.lproj/InfoPlist.strings similarity index 100% rename from openHAB/en.lproj/InfoPlist.strings rename to openHAB/Resources/cs.lproj/InfoPlist.strings diff --git a/openHAB/Resources/cs.lproj/Localizable.strings b/openHAB/Resources/cs.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/cs.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/da.lproj/InfoPlist.strings b/openHAB/Resources/da.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/da.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/da.lproj/Localizable.strings b/openHAB/Resources/da.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/da.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/de.lproj/InfoPlist.strings b/openHAB/Resources/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/de.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/de.lproj/Localizable.strings b/openHAB/Resources/de.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/de.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/el.lproj/InfoPlist.strings b/openHAB/Resources/el.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/el.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/el.lproj/Localizable.strings b/openHAB/Resources/el.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/el.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/en.lproj/Localizable.strings b/openHAB/Resources/en.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/en.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/es.lproj/InfoPlist.strings b/openHAB/Resources/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/es.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/es.lproj/Localizable.strings b/openHAB/Resources/es.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/es.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/fi.lproj/InfoPlist.strings b/openHAB/Resources/fi.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/fi.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/fi.lproj/Localizable.strings b/openHAB/Resources/fi.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/fi.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/fr.lproj/InfoPlist.strings b/openHAB/Resources/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/fr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/fr.lproj/Localizable.strings b/openHAB/Resources/fr.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/fr.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/hu.lproj/InfoPlist.strings b/openHAB/Resources/hu.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/hu.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/hu.lproj/Localizable.strings b/openHAB/Resources/hu.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/hu.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/it.lproj/InfoPlist.strings b/openHAB/Resources/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/it.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/it.lproj/Localizable.strings b/openHAB/Resources/it.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/it.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/nb.lproj/InfoPlist.strings b/openHAB/Resources/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/nb.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/nb.lproj/Localizable.strings b/openHAB/Resources/nb.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/nb.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/nl.lproj/InfoPlist.strings b/openHAB/Resources/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/nl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/nl.lproj/Localizable.strings b/openHAB/Resources/nl.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/nl.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/pl.lproj/InfoPlist.strings b/openHAB/Resources/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/pl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/pl.lproj/Localizable.strings b/openHAB/Resources/pl.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/pl.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/pt-BR.lproj/Localizable.strings b/openHAB/Resources/pt-BR.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/pt-BR.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/pt-PT.lproj/Localizable.strings b/openHAB/Resources/pt-PT.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/pt-PT.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/ro.lproj/InfoPlist.strings b/openHAB/Resources/ro.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/ro.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/ro.lproj/Localizable.strings b/openHAB/Resources/ro.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/ro.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/ru.lproj/InfoPlist.strings b/openHAB/Resources/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/ru.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/ru.lproj/Localizable.strings b/openHAB/Resources/ru.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/ru.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/sr.lproj/InfoPlist.strings b/openHAB/Resources/sr.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/sr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/sr.lproj/Localizable.strings b/openHAB/Resources/sr.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/sr.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/sv-SE.lproj/Localizable.strings b/openHAB/Resources/sv-SE.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/sv-SE.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/tr.lproj/InfoPlist.strings b/openHAB/Resources/tr.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/tr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/tr.lproj/Localizable.strings b/openHAB/Resources/tr.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/tr.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/uk.lproj/InfoPlist.strings b/openHAB/Resources/uk.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/openHAB/Resources/uk.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/uk.lproj/Localizable.strings b/openHAB/Resources/uk.lproj/Localizable.strings new file mode 100644 index 000000000..f2ccd2222 --- /dev/null +++ b/openHAB/Resources/uk.lproj/Localizable.strings @@ -0,0 +1,58 @@ +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; +"sitemap" = "Sitemap"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; +"info" = "Info"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; +"oh_uuid" = "openHAB UUID"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/UILabel+Localization.swift b/openHAB/UILabel+Localization.swift new file mode 100644 index 000000000..b0c891013 --- /dev/null +++ b/openHAB/UILabel+Localization.swift @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import UIKit + +extension UILabel { + @IBInspectable var localizationKey: String { + get { + "" + } + set { + text = NSLocalizedString(newValue, comment: "") + } + } +} diff --git a/openHAB/UIViewController+Localization.swift b/openHAB/UIViewController+Localization.swift new file mode 100644 index 000000000..0ddb77a71 --- /dev/null +++ b/openHAB/UIViewController+Localization.swift @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import UIKit + +extension UIViewController { + @IBInspectable var localizationKey: String { + get { + "" + } + set { + title = NSLocalizedString(newValue, comment: "").uppercased() + } + } +} diff --git a/openHABCore/Sources/Util/ClientCertificateManager.swift b/openHABCore/Sources/Util/ClientCertificateManager.swift index 946fd9e4e..384f86ebf 100644 --- a/openHABCore/Sources/Util/ClientCertificateManager.swift +++ b/openHABCore/Sources/Util/ClientCertificateManager.swift @@ -167,7 +167,7 @@ public class ClientCertificateManager { delegate!.askForCertificatePassword(self) } } else { - let errMsg = "Unable to decode certificate: \(status)." + let errMsg = String(format: NSLocalizedString("unable_to_decode_certificate", comment: ""), "\(status)") if delegate != nil { delegate!.alertClientCertificateError(self, errMsg: errMsg) } @@ -222,9 +222,9 @@ public class ClientCertificateManager { if status != noErr { _ = deleteFromKeychain(importingIdentity!) - var errMsg = "Unable to add certificate to the keychain: \(status)." + var errMsg = String(format: NSLocalizedString("unable_to_add_certificate", comment: ""), "\(status)") if status == errSecDuplicateItem { - errMsg = "Certificate already exists in the keychain." + errMsg = NSLocalizedString("certficate_exists", comment: "") } if delegate != nil { delegate!.alertClientCertificateError(self, errMsg: errMsg) diff --git a/openHABTestsSwift/LocalizationTests.swift b/openHABTestsSwift/LocalizationTests.swift new file mode 100644 index 000000000..b728a327f --- /dev/null +++ b/openHABTestsSwift/LocalizationTests.swift @@ -0,0 +1,150 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +@testable import openHAB +@testable import OpenHABCore +import XCTest + +class LocalizationTests: XCTestCase { + private static var localizations: [String] { + Bundle.main.localizations.filter { $0 != "Base" } + } + + private static let falsePositives: [String] = [] + + private static let localizedFormatStrings: [(key: String, arguments: [CVarArg])] = [(key: "unable_to_decode_certificate", arguments: ["CERTIFICATE_PLACEHOLDER"]), + (key: "unable_to_add_certificate", arguments: ["CERTIFICATE_PLACEHOLDER"]), + (key: "ssl_certificate_invalid", arguments: ["PRESENTER", "SITE"]), + (key: "ssl_certificate_no_match", arguments: ["PRESENTER", "SITE"])] + + func testFormatStrings() { + guard validateFormatStringsCompleteness() else { + XCTFail("'LocalizationTests.localizedFormatStrings' are incomplete.") + return + } + + for language in LocalizationTests.localizations { + print("Testing language: '\(language)'.") + for tuple in LocalizationTests.localizedFormatStrings { + do { + guard let translation = tuple.key.localized(for: language)?.replacingOccurrences(of: "%%", with: "") else { + XCTFail("Failed to get translation for key '\(tuple.key)' in language '\(language)'.") + continue + } + + XCTAssertNotEqual(translation, "__MISSING__", "Missing translation for key '\(tuple.key)' in language '\(language)'.") + let formatSpecifiersRegEx = try NSRegularExpression(pattern: "%(?:\\d+\\$)?[+-]?(?:[lh]{0,2})(?:[qLztj])?(?:[ 0]|'.{1})?\\d*(?:\\.\\d?)?[@dDiuUxXoOfeEgGcCsSpaAFn]") + let numberOfMatches = formatSpecifiersRegEx.numberOfMatches(in: translation, options: [], range: NSRange(location: 0, length: translation.utf16.count)) + XCTAssertEqual(numberOfMatches, tuple.arguments.count, "Invalid number of format specifiers for key '\(tuple.key)' in language '\(language)'.") + } catch { + XCTFail("Failed to create regular expression for key '\(tuple.key)' in language '\(language)'.") + } + let translation = tuple.key.localizedWithFormat(for: language, arguments: tuple.arguments) + XCTAssertNotNil(translation, "Failed to get translation for key '\(tuple.key)' in language '\(language)'.") + print("Translation: \(tuple.key) = \(translation ?? "FAILED")") + } + } + } + + func testLocalizations() { + for language in LocalizationTests.localizations { + print("Testing language: '\(language)'.") + + guard let path = Bundle.main.url(forResource: "Localizable", withExtension: "strings", subdirectory: nil, localization: "en"), + let localizableStrings = NSDictionary(contentsOf: path) as? [String: String], + !localizableStrings.isEmpty + else { + XCTFail("Failed to load bundle.") + return + } + + for localizableString in localizableStrings { + let translation = localizableString.key.localized(for: language) + XCTAssertNotNil(translation, "Failed to get translation for key '\(localizableString.key)' in language '\(language)'.") + XCTAssertNotEqual(translation, "__MISSING__", "Missing translation for key '\(localizableString.key)' in language '\(language)'.") + XCTAssertFalse(translation?.isEmpty ?? true, "Translation for key '\(localizableString.key)' in language '\(language)' is empty.") + print("Translation: \(localizableString.key) = \(translation ?? "FAILED")") + } + } + } + + func testInfoPlistLocalizations() { + let mandatoryKeys: [String] = [] + + if let referencePath = Bundle.main.paths(forResourcesOfType: "strings", inDirectory: "en.lproj").first(where: { $0.contains("InfoPlist.strings") }), + let referenceDictionary = NSDictionary(contentsOfFile: referencePath) as? [String: String] { + for language in LocalizationTests.localizations { + if let path = Bundle.main.paths(forResourcesOfType: "strings", inDirectory: "\(language).lproj").first(where: { $0.contains("InfoPlist.strings") }), + let dictionary = NSDictionary(contentsOfFile: path) as? [String: String] { + for key in mandatoryKeys { + XCTAssertNotNil(dictionary[key], "Missing entry '\(key)' in InfoPlist.strings for language '\(language)'.") + XCTAssertTrue(dictionary[key]?.isEmpty == false, "Missing value for '\(key)' in InfoPlist.strings for language '\(language)'.") + print("\(key) = \(dictionary[key] ?? "MISSING")") + XCTAssertTrue((referenceDictionary[key] ?? "" != dictionary[key] ?? "") || language[0 ..< 2] == "en", "'\(key)' in InfoPlist.strings for language '\(language)' is not properly translated (it is similar to the English term).") + } + } + } + } else { + XCTFail("Failed to load reference InfoPlist.strings.") + } + } + + private func validateFormatStringsCompleteness() -> Bool { + guard let path = Bundle.main.url(forResource: "Localizable", withExtension: "strings", subdirectory: nil, localization: "en"), + let localizableStrings = (NSDictionary(contentsOf: path) as? [String: String])?.filter({ !LocalizationTests.falsePositives.contains($0.key) }), + !localizableStrings.isEmpty + else { + XCTFail("Failed to load bundle.") + return false + } + + var retVal: Bool = true + for localizableString in localizableStrings where localizableString.value.range(of: "%") != nil { + if !LocalizationTests.localizedFormatStrings.contains(where: { $0.key == localizableString.key }) { + retVal = false + XCTFail("Missing translation with key '\(localizableString.key)' in 'LocalizationTests.localizedFormatStrings'.") + } + } + + return retVal + } +} + +private extension String { + func localized(for language: String) -> String? { + guard let path = Bundle.main.path(forResource: language, ofType: "lproj") else { + return nil + } + + return Bundle(path: path)?.localizedString(forKey: self, value: "__MISSING__", table: nil) + } + + func localizedWithFormat(for language: String, arguments: [CVarArg]) -> String? { + if let string = localized(for: language) { + return String(format: string, arguments: arguments) + } + + return nil + } + + subscript(bounds: CountableClosedRange) -> String { + let start = index(startIndex, offsetBy: bounds.lowerBound) + let end = index(startIndex, offsetBy: bounds.upperBound) + return String(self[start ... end]) + } + + subscript(bounds: CountableRange) -> String { + let start = index(startIndex, offsetBy: bounds.lowerBound) + let end = index(startIndex, offsetBy: bounds.upperBound) + return String(self[start ..< end]) + } +} diff --git a/openHABWatch Extension/ExtensionDelegate.swift b/openHABWatch Extension/ExtensionDelegate.swift index ace470986..daf28d1ce 100644 --- a/openHABWatch Extension/ExtensionDelegate.swift +++ b/openHABWatch Extension/ExtensionDelegate.swift @@ -129,7 +129,7 @@ extension ExtensionDelegate: ServerCertificateManagerDelegate { } DispatchQueue.main.async { self.viewModel?.showCertificateAlert = true - self.viewModel?.certificateErrorDescription = "SSL Certificate presented by \(certificateSummary ?? "") for \(domain ?? "") is invalid. Do you want to proceed?" + self.viewModel?.certificateErrorDescription = String(format: NSLocalizedString("ssl_certificate_invalid", comment: ""), certificateSummary ?? "", domain ?? "") } } @@ -141,7 +141,7 @@ extension ExtensionDelegate: ServerCertificateManagerDelegate { } DispatchQueue.main.async { self.viewModel?.showCertificateAlert = true - self.viewModel?.certificateErrorDescription = "SSL Certificate presented by \(certificateSummary ?? "") for \(domain ?? "") doesn't match the record. Do you want to proceed?" + self.viewModel?.certificateErrorDescription = String(format: NSLocalizedString("ssl_certificate_no_match", comment: ""), certificateSummary ?? "", domain ?? "") } } diff --git a/openHABWatch Extension/OpenHABWatchTracker.swift b/openHABWatch Extension/OpenHABWatchTracker.swift index 75f5b4b93..c4f0e13aa 100644 --- a/openHABWatch Extension/OpenHABWatchTracker.swift +++ b/openHABWatch Extension/OpenHABWatchTracker.swift @@ -99,14 +99,14 @@ class OpenHABWatchTracker: NSObject { } } else { var errorDetail: [AnyHashable: Any] = [:] - errorDetail[NSLocalizedDescriptionKey] = "Network is not available." + errorDetail[NSLocalizedDescriptionKey] = NSLocalizedString("network_not_available", comment: "") let trackingError = NSError(domain: "openHAB", code: 100, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } } func trackedLocalUrl() { - delegate?.openHABTrackingProgress("Connecting to local URL") + delegate?.openHABTrackingProgress(NSLocalizedString("connecting_local", comment: "")) let openHABUrl = normalizeUrl(ObservableOpenHABDataObject.shared.localUrl) trackedUrl(URL(string: openHABUrl!)) } @@ -118,19 +118,19 @@ class OpenHABWatchTracker: NSObject { trackedUrl(URL(string: openHABUrl!)) } else { var errorDetail: [AnyHashable: Any] = [:] - errorDetail[NSLocalizedDescriptionKey] = "Remote URL is not configured." + errorDetail[NSLocalizedDescriptionKey] = NSLocalizedString("remote_url_not_configured", comment: "") let trackingError = NSError(domain: "openHAB", code: 101, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } } func trackedDiscoveryUrl(_ discoveryUrl: URL?) { - delegate?.openHABTrackingProgress("Connecting to discovered URL") + delegate?.openHABTrackingProgress(NSLocalizedString("connecting_discovered", comment: "")) trackedUrl(discoveryUrl) } func trackedDemoMode() { - delegate?.openHABTrackingProgress("Running in demo mode. Check settings to disable demo mode.") + delegate?.openHABTrackingProgress(NSLocalizedString("running_demo_mode", comment: "")) trackedUrl(URL(staticString: "http://demo.openhab.org:8080")) } @@ -141,7 +141,7 @@ class OpenHABWatchTracker: NSObject { func startDiscovery() { os_log("OpenHABTracking starting Bonjour discovery", log: .default, type: .info) - delegate?.openHABTrackingProgress("Discovering openHAB") + delegate?.openHABTrackingProgress(NSLocalizedString("discovering_oh", comment: "")) let parameters = NWParameters() netBrowser = NWBrowser(for: .bonjour(type: "_openhab-server-ssl._tcp.", domain: "local."), using: parameters) netBrowser?.stateUpdateHandler = { state in diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index a7c20648f..16d299cd9 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -28,9 +28,9 @@ struct ContentView: View { } .navigationBarTitle(Text(title)) .alert(isPresented: $viewModel.showAlert) { - Alert(title: Text("Error"), + Alert(title: Text(NSLocalizedString("error", comment: "")), message: Text(viewModel.errorDescription), - dismissButton: .default(Text("Retry")) { + dismissButton: .default(Text(NSLocalizedString("retry", comment: ""))) { DispatchQueue.main.async { self.viewModel.refreshUrl() os_log("reload after alert", log: .default, type: .info) @@ -38,15 +38,15 @@ struct ContentView: View { }) } .actionSheet(isPresented: $viewModel.showCertificateAlert) { - ActionSheet(title: Text("Warning"), + ActionSheet(title: Text(NSLocalizedString("warning", comment: "")), message: Text(viewModel.certificateErrorDescription), - buttons: [.default(Text("Abort")) { + buttons: [.default(Text(NSLocalizedString("abort", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .deny }, - .default(Text("Once")) { + .default(Text(NSLocalizedString("once", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitOnce }, - .default(Text("Always")) { + .default(Text(NSLocalizedString("always", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitAlways }]) } diff --git a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift index c609f8fd5..2ab21e503 100644 --- a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift +++ b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift @@ -27,14 +27,14 @@ struct PreferencesSwiftUIView: View { var body: some View { List { - PreferencesRowUIView(label: "Version", content: applicationVersionNumber).font(.footnote) - PreferencesRowUIView(label: "Active URL", content: settings.openHABRootUrl).font(.footnote) - PreferencesRowUIView(label: "Local URL", content: settings.localUrl).font(.footnote) - PreferencesRowUIView(label: "Remote URL", content: settings.remoteUrl).font(.footnote) - PreferencesRowUIView(label: "Sitemap", content: settings.sitemapName).font(.footnote) - PreferencesRowUIView(label: "Username", content: settings.openHABUsername).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("version", comment: ""), content: applicationVersionNumber).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("active_url", comment: ""), content: settings.openHABRootUrl).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("local_url", comment: ""), content: settings.localUrl).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("remote_url", comment: ""), content: settings.remoteUrl).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("sitemap", comment: ""), content: settings.sitemapName).font(.footnote) + PreferencesRowUIView(label: NSLocalizedString("username", comment: ""), content: settings.openHABUsername).font(.footnote) HStack { - Button(action: { AppMessageService.singleton.requestApplicationContext() }, label: { Text("Sync preferences") }) + Button(action: { AppMessageService.singleton.requestApplicationContext() }, label: { Text(NSLocalizedString("sync_prefs", comment: "")) }) } } } diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 28d3dd1a0..ef91474c2 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -235,7 +235,7 @@ extension UserData: OpenHABWatchTrackerDelegate { if !ObservableOpenHABDataObject.shared.haveReceivedAppContext { AppMessageService.singleton.requestApplicationContext() - errorDescription = "Settings not yet received from phone." + errorDescription = NSLocalizedString("settings_not_received", comment: "") showAlert = true return } diff --git a/openHABWatch/it.lproj/Interface.strings b/openHABWatch/it.lproj/Interface.strings new file mode 100644 index 000000000..6f6372118 --- /dev/null +++ b/openHABWatch/it.lproj/Interface.strings @@ -0,0 +1,3 @@ + +/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ +"IdU-wH-bcW.text" = "Alert Label"; From dbb10b36d26656ee32e01e67c61ddb7149fc8a21 Mon Sep 17 00:00:00 2001 From: openhab-bot Date: Tue, 25 Aug 2020 00:08:39 +0200 Subject: [PATCH 29/78] Update Crowdin configuration file --- crowdin.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 crowdin.yml diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..3946523d2 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,3 @@ +files: + - source: /openHAB/Resources/en.lproj/*.strings + translation: /openHAB/Resources/%two_letters_code%.lproj/%original_file_name% From 91f5570aada0061f49cb2400408d6cc24208c953 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 08:42:58 +0200 Subject: [PATCH 30/78] test crowdin language mapping --- crowdin.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crowdin.yml b/crowdin.yml index 3946523d2..82b21ca2c 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,9 @@ files: - source: /openHAB/Resources/en.lproj/*.strings translation: /openHAB/Resources/%two_letters_code%.lproj/%original_file_name% + languages_mapping: + two_letters_code: + es-ES: es + no: nb + pt-PT: pt-PT + sv-SE: sv-SE From a975a403d79b1233e391ba98277a3dab6c36a486 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 09:09:08 +0200 Subject: [PATCH 31/78] update crowdin configuration --- crowdin.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 82b21ca2c..4e9ed9a2d 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,9 +1,3 @@ files: - source: /openHAB/Resources/en.lproj/*.strings - translation: /openHAB/Resources/%two_letters_code%.lproj/%original_file_name% - languages_mapping: - two_letters_code: - es-ES: es - no: nb - pt-PT: pt-PT - sv-SE: sv-SE + translation: /openHAB/Resources/%locale%.lproj/%original_file_name% From 0af68e4921fc78476c12abbc5c1dd5e8b94ccd54 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 09:41:09 +0200 Subject: [PATCH 32/78] temporary fix for crowdin lane --- fastlane/Fastfile | 2 +- openHAB/Resources/crowdinfiles.yml | 41 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4c52e24b1..4ef4c8d37 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -145,7 +145,7 @@ platform :ios do langs = config['langs'] # Expected size of the array, used to check if new languages have been added or not # The size logic can be omitted if needed - size = 42 + size = 63 response = Net::HTTP.get_response(URI(build)) if response.is_a? Net::HTTPSuccess diff --git a/openHAB/Resources/crowdinfiles.yml b/openHAB/Resources/crowdinfiles.yml index c7479d2b8..8a2ba13d1 100644 --- a/openHAB/Resources/crowdinfiles.yml +++ b/openHAB/Resources/crowdinfiles.yml @@ -1,43 +1,42 @@ langs: - en/Localizable.strings: + develop/openHAB/Resources/en.lproj/Localizable.strings: - en.lproj - de/Localizable.strings: + develop/openHAB/Resources/de.lproj/Localizable.strings: - de.lproj - es-ES/Localizable.strings: + develop/openHAB/Resources/es.lproj/Localizable.strings: - es.lproj - it/Localizable.strings: + develop/openHAB/Resources/it.lproj/Localizable.strings: - it.lproj - cs/Localizable.strings: + develop/openHAB/Resources/cs.lproj/Localizable.strings: - cs.lproj - da/Localizable.strings: + develop/openHAB/Resources/da.lproj/Localizable.strings: - da.lproj - el/Localizable.strings: + develop/openHAB/Resources/el.lproj/Localizable.strings: - el.lproj - fi/Localizable.strings: + develop/openHAB/Resources/fi.lproj/Localizable.strings: - fi.lproj - fr/Localizable.strings: + develop/openHAB/Resources/fr.lproj/Localizable.strings: - fr.lproj - hu/Localizable.strings: + develop/openHAB/Resources/hu.lproj/Localizable.strings: - hu.lproj - nl/Localizable.strings: + develop/openHAB/Resources/nl.lproj/Localizable.strings: - nl.lproj - no/Localizable.strings: + develop/openHAB/Resources/no.lproj/Localizable.strings: - nb.lproj - pl/Localizable.strings: + develop/openHAB/Resources/pl.lproj/Localizable.strings: - pl.lproj - pt-PT/Localizable.strings: + develop/openHAB/Resources/pt.lproj/Localizable.strings: - pt-PT.lproj - pt-BR/Localizable.strings: - pt-BR.lproj - ro/Localizable.strings: + develop/openHAB/Resources/ro.lproj/Localizable.strings: - ro.lproj - ru/Localizable.strings: + develop/openHAB/Resources/ru.lproj/Localizable.strings: - ru.lproj - sr/Localizable.strings: + develop/openHAB/Resources/sr.lproj/Localizable.strings: - sr.lproj - sv-SE/Localizable.strings: + develop/openHAB/Resources/sv.lproj/Localizable.strings: - sv-SE.lproj - tr/Localizable.strings: + develop/openHAB/Resources/tr.lproj/Localizable.strings: - tr.lproj - uk/Localizable.strings: + develop/openHAB/Resources/uk.lproj/Localizable.strings: - uk.lproj From 52e42fc36cfcc22258f569cc65c0c813ef7bc434 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 09:43:49 +0200 Subject: [PATCH 33/78] add dutch translations --- .../Resources/nl.lproj/Localizable.strings | 110 +++++++++--------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/openHAB/Resources/nl.lproj/Localizable.strings b/openHAB/Resources/nl.lproj/Localizable.strings index f2ccd2222..d45bd91ca 100644 --- a/openHAB/Resources/nl.lproj/Localizable.strings +++ b/openHAB/Resources/nl.lproj/Localizable.strings @@ -1,58 +1,58 @@ -"certficate_exists" = "Certificate already exists in the keychain."; -"message_not_decoded" = "Message could not be decoded"; -"notification" = "Notification"; -"dismiss" = "Dismiss"; -"search_items" = "Search openHAB items"; -"error" = "Error"; -"ssl_certificate_error" = "SSL Certificate Error"; -"empty_sitemap" = "openHAB returned empty sitemap list"; -"connecting" = "Connecting"; -"ssl_certificate_warning" = "SSL Certificate Warning"; -"unable_to_decode_certificate" = "Unable to decode certificate: %@."; -"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; -"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; -"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; -"abort" = "Abort"; -"once" = "Once"; -"always" = "Always"; -"certificate_import_title" = "Client Certificate Import"; -"certificate_import_text" = "Import client certificate into the keychain?"; -"certificate_import_password" = "Password required for import."; -"okay" = "Okay"; -"cancel" = "Cancel"; -"password" = "Password"; -"copy_label" = "Copy item label"; -"network_not_available" = "Network is not available."; -"connecting_local" = "Connecting to local URL"; -"remote_url_not_configured" = "Remote URL is not configured."; -"connecting_discovered" = "Connecting to discovered URL"; -"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; -"discovering_oh" = "Discovering openHAB"; -"settings_not_received" = "Settings not yet received from phone."; -"retry" = "Retry"; -"warning" = "Warning"; -"version" = "Version"; -"active_url" = "Active URL"; -"local_url" = "Local URL"; -"remote_url" = "Remote URL"; +"certficate_exists" = "Certificaat bestaat al in de sleutelhanger."; +"message_not_decoded" = "Bericht kon niet gedecodeerd worden"; +"notification" = "Notificatie"; +"dismiss" = "Afwijzen"; +"search_items" = "Zoek openHAB items"; +"error" = "Fout"; +"ssl_certificate_error" = "SSL-certificaat fout"; +"empty_sitemap" = "openHAB heeft een lege Sitemap geladen"; +"connecting" = "Verbinden"; +"ssl_certificate_warning" = "SSL-certificaat waarschuwing"; +"unable_to_decode_certificate" = "Kan certificaat niet decoderen: %@."; +"unable_to_add_certificate" = "Kan certificaat niet toevoegen aan de sleutelhanger: %@."; +"ssl_certificate_invalid" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ is ongeldig. Wilt u toch doorgaan?"; +"ssl_certificate_no_match" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ komt niet overeen met het record. Wilt u toch doorgaan?"; +"abort" = "Afbreken"; +"once" = "Eenmalig"; +"always" = "Altijd"; +"certificate_import_title" = "Cliëntcertificaat Importeren"; +"certificate_import_text" = "Client-certificaat in de sleutelhanger importeren?"; +"certificate_import_password" = "Wachtwoord vereist voor import."; +"okay" = "Oké"; +"cancel" = "Annuleer"; +"password" = "Wachtwoord"; +"copy_label" = "Item label kopiëren"; +"network_not_available" = "Netwerk is niet beschikbaar."; +"connecting_local" = "Verbinden naar lokale URL"; +"remote_url_not_configured" = "Externe URL is niet geconfigureerd."; +"connecting_discovered" = "Verbinden naar gevonden URL"; +"running_demo_mode" = "Uitvoeren in demo-modus. Controleer instellingen om demomodus uit te schakelen."; +"discovering_oh" = "Bezig met zoeken naar openHAB"; +"settings_not_received" = "Instellingen nog niet ontvangen van telefoon."; +"retry" = "Opnieuw"; +"warning" = "Waarschuwing"; +"version" = "Versie"; +"active_url" = "Actieve URL"; +"local_url" = "Lokale URL"; +"remote_url" = "Externe URL"; "sitemap" = "Sitemap"; -"username" = "Username"; -"sync_prefs" = "Sync preferences"; -"demo_mode" = "Demo mode"; -"always_send_credentials" = "Always send credentials"; -"ignore_ssl_certificates" = "Ignore SSL Certificates"; -"client_certificates" = "Client Certificates"; -"disable_idle_timeout" = "Disable Idle Timeout"; -"real_time_sliders" = "Real-time Sliders"; -"clear_image_cache" = "Clear Image Cache"; -"icon_type" = "Icon Type"; +"username" = "Gebruikersnaam"; +"sync_prefs" = "Synchronisatie voorkeuren"; +"demo_mode" = "Demomodus"; +"always_send_credentials" = "Altijd inloggegevens versturen"; +"ignore_ssl_certificates" = "Negeer SSL-certificaten"; +"client_certificates" = "Cliëntcertificaat"; +"disable_idle_timeout" = "Schermtimeout uitschakelen"; +"real_time_sliders" = "Realtime schuifregelaars"; +"clear_image_cache" = "Leeg de afbeeldingencache"; +"icon_type" = "Icoontype"; "info" = "Info"; -"select_sitemap" = "Select Sitemap"; -"crash_reporting" = "Crash Reporting"; -"legal" = "Legal"; -"openhab_connection" = "openHAB Connection"; -"application_settings" = "Application Settings"; -"app_version" = "App Version"; -"oh_version" = "openHAB Version"; +"select_sitemap" = "Selecteer Sitemap"; +"crash_reporting" = "Foutenrapportering"; +"legal" = "Juridisch"; +"openhab_connection" = "openHAB Verbinding"; +"application_settings" = "Applicatie Instellingen"; +"app_version" = "App Versie"; +"oh_version" = "openHAB Versie"; "oh_uuid" = "openHAB UUID"; -"oh_secret" = "openHAB Secret"; +"oh_secret" = "openHAB geheim"; From 027202fdc1a8fb3c4632992a1b5116038095d624 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 10:06:33 +0200 Subject: [PATCH 34/78] use nb for Norwegian --- openHAB/Resources/crowdinfiles.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openHAB/Resources/crowdinfiles.yml b/openHAB/Resources/crowdinfiles.yml index 8a2ba13d1..31ac5be80 100644 --- a/openHAB/Resources/crowdinfiles.yml +++ b/openHAB/Resources/crowdinfiles.yml @@ -21,7 +21,7 @@ langs: - hu.lproj develop/openHAB/Resources/nl.lproj/Localizable.strings: - nl.lproj - develop/openHAB/Resources/no.lproj/Localizable.strings: + develop/openHAB/Resources/nb.lproj/Localizable.strings: - nb.lproj develop/openHAB/Resources/pl.lproj/Localizable.strings: - pl.lproj From 716c9d08294f016f70d72379dc7048a0e44ddb76 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 18:45:41 +0200 Subject: [PATCH 35/78] update crowdin configuration --- crowdin.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crowdin.yml b/crowdin.yml index 4e9ed9a2d..0603ff2b9 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,23 @@ files: - source: /openHAB/Resources/en.lproj/*.strings translation: /openHAB/Resources/%locale%.lproj/%original_file_name% + languages_mapping: + locale: + cs-CZ: cs + da-DK: da + de-DE: de + el-GR: el + en-US: en + es-ES: es + fi-FI: fi + fr-FR: fr + hu-HU: hu + it-IT: it + nb-NO: nb + nl-NL: nl + pl-PL: pl + ro-RO: ro + ru-RU: ru + sr-SP: sr + tr-TR: tr + uk-UA: uk From e6b5bd3037cc4a38e26369fbddf4474c6d496033 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 19:05:19 +0200 Subject: [PATCH 36/78] update crowdin configuration --- crowdin.yml | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 0603ff2b9..9a8afd426 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,23 +1,7 @@ files: - source: /openHAB/Resources/en.lproj/*.strings - translation: /openHAB/Resources/%locale%.lproj/%original_file_name% + translation: /openHAB/Resources/%two_letters_code%.lproj/%original_file_name% languages_mapping: - locale: - cs-CZ: cs - da-DK: da - de-DE: de - el-GR: el - en-US: en - es-ES: es - fi-FI: fi - fr-FR: fr - hu-HU: hu - it-IT: it - nb-NO: nb - nl-NL: nl - pl-PL: pl - ro-RO: ro - ru-RU: ru - sr-SP: sr - tr-TR: tr - uk-UA: uk + two_letters_code: + pt: pt-PT + sv: sv-SE From ce77ee511ec45fb79ee4fb4aabb48dd3379a2ec0 Mon Sep 17 00:00:00 2001 From: weak Date: Tue, 25 Aug 2020 19:16:10 +0200 Subject: [PATCH 37/78] Revert "update crowdin configuration" This reverts commit e6b5bd3037cc4a38e26369fbddf4474c6d496033. --- crowdin.yml | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 9a8afd426..0603ff2b9 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,7 +1,23 @@ files: - source: /openHAB/Resources/en.lproj/*.strings - translation: /openHAB/Resources/%two_letters_code%.lproj/%original_file_name% + translation: /openHAB/Resources/%locale%.lproj/%original_file_name% languages_mapping: - two_letters_code: - pt: pt-PT - sv: sv-SE + locale: + cs-CZ: cs + da-DK: da + de-DE: de + el-GR: el + en-US: en + es-ES: es + fi-FI: fi + fr-FR: fr + hu-HU: hu + it-IT: it + nb-NO: nb + nl-NL: nl + pl-PL: pl + ro-RO: ro + ru-RU: ru + sr-SP: sr + tr-TR: tr + uk-UA: uk From 353c9b5f75e0c845b70d94622d5f789065516daf Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 08:24:04 +0200 Subject: [PATCH 38/78] update crowdin configuration --- crowdin.yml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/crowdin.yml b/crowdin.yml index 0603ff2b9..e32bd6bc8 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,23 +1,3 @@ files: - source: /openHAB/Resources/en.lproj/*.strings - translation: /openHAB/Resources/%locale%.lproj/%original_file_name% - languages_mapping: - locale: - cs-CZ: cs - da-DK: da - de-DE: de - el-GR: el - en-US: en - es-ES: es - fi-FI: fi - fr-FR: fr - hu-HU: hu - it-IT: it - nb-NO: nb - nl-NL: nl - pl-PL: pl - ro-RO: ro - ru-RU: ru - sr-SP: sr - tr-TR: tr - uk-UA: uk + translation: /openHAB/Resources/%osx_locale%.lproj/%original_file_name% From 3b01d87eb71aaff5e2fd860d0341b9ccc063d740 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 08:50:34 +0200 Subject: [PATCH 39/78] update crowdin configuration --- crowdin.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crowdin.yml b/crowdin.yml index e32bd6bc8..d468c2b05 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,8 @@ files: - source: /openHAB/Resources/en.lproj/*.strings translation: /openHAB/Resources/%osx_locale%.lproj/%original_file_name% + languages_mapping: + osx_locale: + pt-BR: pt-BR + pt-PT: pt-PT + sv-SE: sv-SE From 7b6a5f89ea184768689aedb858e5b6ebbd0b3f63 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 09:04:42 +0200 Subject: [PATCH 40/78] update InfoPlist.strings --- openHAB/Resources/cs.lproj/InfoPlist.strings | 2 - openHAB/Resources/da.lproj/InfoPlist.strings | 2 - openHAB/Resources/de.lproj/InfoPlist.strings | 2 - openHAB/Resources/el.lproj/InfoPlist.strings | 2 - openHAB/Resources/en.lproj/InfoPlist.strings | 2 - openHAB/Resources/es.lproj/InfoPlist.strings | 2 - openHAB/Resources/fi.lproj/InfoPlist.strings | 2 - openHAB/Resources/fr.lproj/InfoPlist.strings | 2 - openHAB/Resources/hu.lproj/InfoPlist.strings | 2 - openHAB/Resources/it.lproj/InfoPlist.strings | 2 - openHAB/Resources/nb.lproj/InfoPlist.strings | 2 - openHAB/Resources/nl.lproj/InfoPlist.strings | 2 - .../Resources/nl.lproj/Localizable.strings | 110 +++++++++--------- openHAB/Resources/pl.lproj/InfoPlist.strings | 2 - .../Resources/pt-BR.lproj/InfoPlist.strings | 2 - .../Resources/pt-PT.lproj/InfoPlist.strings | 2 - openHAB/Resources/ro.lproj/InfoPlist.strings | 2 - openHAB/Resources/ru.lproj/InfoPlist.strings | 2 - openHAB/Resources/sr.lproj/InfoPlist.strings | 2 - .../Resources/sv-SE.lproj/InfoPlist.strings | 2 - openHAB/Resources/tr.lproj/InfoPlist.strings | 2 - openHAB/Resources/uk.lproj/InfoPlist.strings | 2 - 22 files changed, 55 insertions(+), 97 deletions(-) diff --git a/openHAB/Resources/cs.lproj/InfoPlist.strings b/openHAB/Resources/cs.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/cs.lproj/InfoPlist.strings +++ b/openHAB/Resources/cs.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/da.lproj/InfoPlist.strings b/openHAB/Resources/da.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/da.lproj/InfoPlist.strings +++ b/openHAB/Resources/da.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/de.lproj/InfoPlist.strings b/openHAB/Resources/de.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/de.lproj/InfoPlist.strings +++ b/openHAB/Resources/de.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/el.lproj/InfoPlist.strings b/openHAB/Resources/el.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/el.lproj/InfoPlist.strings +++ b/openHAB/Resources/el.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/es.lproj/InfoPlist.strings b/openHAB/Resources/es.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/es.lproj/InfoPlist.strings +++ b/openHAB/Resources/es.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/fi.lproj/InfoPlist.strings b/openHAB/Resources/fi.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/fi.lproj/InfoPlist.strings +++ b/openHAB/Resources/fi.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/fr.lproj/InfoPlist.strings b/openHAB/Resources/fr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/fr.lproj/InfoPlist.strings +++ b/openHAB/Resources/fr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/hu.lproj/InfoPlist.strings b/openHAB/Resources/hu.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/hu.lproj/InfoPlist.strings +++ b/openHAB/Resources/hu.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/it.lproj/InfoPlist.strings b/openHAB/Resources/it.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/it.lproj/InfoPlist.strings +++ b/openHAB/Resources/it.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/nb.lproj/InfoPlist.strings b/openHAB/Resources/nb.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/nb.lproj/InfoPlist.strings +++ b/openHAB/Resources/nb.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/nl.lproj/InfoPlist.strings b/openHAB/Resources/nl.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/nl.lproj/InfoPlist.strings +++ b/openHAB/Resources/nl.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/nl.lproj/Localizable.strings b/openHAB/Resources/nl.lproj/Localizable.strings index d45bd91ca..f2ccd2222 100644 --- a/openHAB/Resources/nl.lproj/Localizable.strings +++ b/openHAB/Resources/nl.lproj/Localizable.strings @@ -1,58 +1,58 @@ -"certficate_exists" = "Certificaat bestaat al in de sleutelhanger."; -"message_not_decoded" = "Bericht kon niet gedecodeerd worden"; -"notification" = "Notificatie"; -"dismiss" = "Afwijzen"; -"search_items" = "Zoek openHAB items"; -"error" = "Fout"; -"ssl_certificate_error" = "SSL-certificaat fout"; -"empty_sitemap" = "openHAB heeft een lege Sitemap geladen"; -"connecting" = "Verbinden"; -"ssl_certificate_warning" = "SSL-certificaat waarschuwing"; -"unable_to_decode_certificate" = "Kan certificaat niet decoderen: %@."; -"unable_to_add_certificate" = "Kan certificaat niet toevoegen aan de sleutelhanger: %@."; -"ssl_certificate_invalid" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ is ongeldig. Wilt u toch doorgaan?"; -"ssl_certificate_no_match" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ komt niet overeen met het record. Wilt u toch doorgaan?"; -"abort" = "Afbreken"; -"once" = "Eenmalig"; -"always" = "Altijd"; -"certificate_import_title" = "Cliëntcertificaat Importeren"; -"certificate_import_text" = "Client-certificaat in de sleutelhanger importeren?"; -"certificate_import_password" = "Wachtwoord vereist voor import."; -"okay" = "Oké"; -"cancel" = "Annuleer"; -"password" = "Wachtwoord"; -"copy_label" = "Item label kopiëren"; -"network_not_available" = "Netwerk is niet beschikbaar."; -"connecting_local" = "Verbinden naar lokale URL"; -"remote_url_not_configured" = "Externe URL is niet geconfigureerd."; -"connecting_discovered" = "Verbinden naar gevonden URL"; -"running_demo_mode" = "Uitvoeren in demo-modus. Controleer instellingen om demomodus uit te schakelen."; -"discovering_oh" = "Bezig met zoeken naar openHAB"; -"settings_not_received" = "Instellingen nog niet ontvangen van telefoon."; -"retry" = "Opnieuw"; -"warning" = "Waarschuwing"; -"version" = "Versie"; -"active_url" = "Actieve URL"; -"local_url" = "Lokale URL"; -"remote_url" = "Externe URL"; +"certficate_exists" = "Certificate already exists in the keychain."; +"message_not_decoded" = "Message could not be decoded"; +"notification" = "Notification"; +"dismiss" = "Dismiss"; +"search_items" = "Search openHAB items"; +"error" = "Error"; +"ssl_certificate_error" = "SSL Certificate Error"; +"empty_sitemap" = "openHAB returned empty sitemap list"; +"connecting" = "Connecting"; +"ssl_certificate_warning" = "SSL Certificate Warning"; +"unable_to_decode_certificate" = "Unable to decode certificate: %@."; +"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; +"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; +"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; +"abort" = "Abort"; +"once" = "Once"; +"always" = "Always"; +"certificate_import_title" = "Client Certificate Import"; +"certificate_import_text" = "Import client certificate into the keychain?"; +"certificate_import_password" = "Password required for import."; +"okay" = "Okay"; +"cancel" = "Cancel"; +"password" = "Password"; +"copy_label" = "Copy item label"; +"network_not_available" = "Network is not available."; +"connecting_local" = "Connecting to local URL"; +"remote_url_not_configured" = "Remote URL is not configured."; +"connecting_discovered" = "Connecting to discovered URL"; +"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; +"discovering_oh" = "Discovering openHAB"; +"settings_not_received" = "Settings not yet received from phone."; +"retry" = "Retry"; +"warning" = "Warning"; +"version" = "Version"; +"active_url" = "Active URL"; +"local_url" = "Local URL"; +"remote_url" = "Remote URL"; "sitemap" = "Sitemap"; -"username" = "Gebruikersnaam"; -"sync_prefs" = "Synchronisatie voorkeuren"; -"demo_mode" = "Demomodus"; -"always_send_credentials" = "Altijd inloggegevens versturen"; -"ignore_ssl_certificates" = "Negeer SSL-certificaten"; -"client_certificates" = "Cliëntcertificaat"; -"disable_idle_timeout" = "Schermtimeout uitschakelen"; -"real_time_sliders" = "Realtime schuifregelaars"; -"clear_image_cache" = "Leeg de afbeeldingencache"; -"icon_type" = "Icoontype"; +"username" = "Username"; +"sync_prefs" = "Sync preferences"; +"demo_mode" = "Demo mode"; +"always_send_credentials" = "Always send credentials"; +"ignore_ssl_certificates" = "Ignore SSL Certificates"; +"client_certificates" = "Client Certificates"; +"disable_idle_timeout" = "Disable Idle Timeout"; +"real_time_sliders" = "Real-time Sliders"; +"clear_image_cache" = "Clear Image Cache"; +"icon_type" = "Icon Type"; "info" = "Info"; -"select_sitemap" = "Selecteer Sitemap"; -"crash_reporting" = "Foutenrapportering"; -"legal" = "Juridisch"; -"openhab_connection" = "openHAB Verbinding"; -"application_settings" = "Applicatie Instellingen"; -"app_version" = "App Versie"; -"oh_version" = "openHAB Versie"; +"select_sitemap" = "Select Sitemap"; +"crash_reporting" = "Crash Reporting"; +"legal" = "Legal"; +"openhab_connection" = "openHAB Connection"; +"application_settings" = "Application Settings"; +"app_version" = "App Version"; +"oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; -"oh_secret" = "openHAB geheim"; +"oh_secret" = "openHAB Secret"; diff --git a/openHAB/Resources/pl.lproj/InfoPlist.strings b/openHAB/Resources/pl.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pl.lproj/InfoPlist.strings +++ b/openHAB/Resources/pl.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/ro.lproj/InfoPlist.strings b/openHAB/Resources/ro.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/ro.lproj/InfoPlist.strings +++ b/openHAB/Resources/ro.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/ru.lproj/InfoPlist.strings b/openHAB/Resources/ru.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/ru.lproj/InfoPlist.strings +++ b/openHAB/Resources/ru.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/sr.lproj/InfoPlist.strings b/openHAB/Resources/sr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/sr.lproj/InfoPlist.strings +++ b/openHAB/Resources/sr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings +++ b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/tr.lproj/InfoPlist.strings b/openHAB/Resources/tr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/tr.lproj/InfoPlist.strings +++ b/openHAB/Resources/tr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/uk.lproj/InfoPlist.strings b/openHAB/Resources/uk.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/uk.lproj/InfoPlist.strings +++ b/openHAB/Resources/uk.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - From d202e15a78204b7b0a51d7d87283ee2c6c78b1c1 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 09:09:29 +0200 Subject: [PATCH 41/78] Revert "update InfoPlist.strings" This reverts commit 7b6a5f89ea184768689aedb858e5b6ebbd0b3f63. --- openHAB/Resources/cs.lproj/InfoPlist.strings | 2 + openHAB/Resources/da.lproj/InfoPlist.strings | 2 + openHAB/Resources/de.lproj/InfoPlist.strings | 2 + openHAB/Resources/el.lproj/InfoPlist.strings | 2 + openHAB/Resources/en.lproj/InfoPlist.strings | 2 + openHAB/Resources/es.lproj/InfoPlist.strings | 2 + openHAB/Resources/fi.lproj/InfoPlist.strings | 2 + openHAB/Resources/fr.lproj/InfoPlist.strings | 2 + openHAB/Resources/hu.lproj/InfoPlist.strings | 2 + openHAB/Resources/it.lproj/InfoPlist.strings | 2 + openHAB/Resources/nb.lproj/InfoPlist.strings | 2 + openHAB/Resources/nl.lproj/InfoPlist.strings | 2 + .../Resources/nl.lproj/Localizable.strings | 110 +++++++++--------- openHAB/Resources/pl.lproj/InfoPlist.strings | 2 + .../Resources/pt-BR.lproj/InfoPlist.strings | 2 + .../Resources/pt-PT.lproj/InfoPlist.strings | 2 + openHAB/Resources/ro.lproj/InfoPlist.strings | 2 + openHAB/Resources/ru.lproj/InfoPlist.strings | 2 + openHAB/Resources/sr.lproj/InfoPlist.strings | 2 + .../Resources/sv-SE.lproj/InfoPlist.strings | 2 + openHAB/Resources/tr.lproj/InfoPlist.strings | 2 + openHAB/Resources/uk.lproj/InfoPlist.strings | 2 + 22 files changed, 97 insertions(+), 55 deletions(-) diff --git a/openHAB/Resources/cs.lproj/InfoPlist.strings b/openHAB/Resources/cs.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/cs.lproj/InfoPlist.strings +++ b/openHAB/Resources/cs.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/da.lproj/InfoPlist.strings b/openHAB/Resources/da.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/da.lproj/InfoPlist.strings +++ b/openHAB/Resources/da.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/de.lproj/InfoPlist.strings b/openHAB/Resources/de.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/de.lproj/InfoPlist.strings +++ b/openHAB/Resources/de.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/el.lproj/InfoPlist.strings b/openHAB/Resources/el.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/el.lproj/InfoPlist.strings +++ b/openHAB/Resources/el.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/es.lproj/InfoPlist.strings b/openHAB/Resources/es.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/es.lproj/InfoPlist.strings +++ b/openHAB/Resources/es.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/fi.lproj/InfoPlist.strings b/openHAB/Resources/fi.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/fi.lproj/InfoPlist.strings +++ b/openHAB/Resources/fi.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/fr.lproj/InfoPlist.strings b/openHAB/Resources/fr.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/fr.lproj/InfoPlist.strings +++ b/openHAB/Resources/fr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/hu.lproj/InfoPlist.strings b/openHAB/Resources/hu.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/hu.lproj/InfoPlist.strings +++ b/openHAB/Resources/hu.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/it.lproj/InfoPlist.strings b/openHAB/Resources/it.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/it.lproj/InfoPlist.strings +++ b/openHAB/Resources/it.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/nb.lproj/InfoPlist.strings b/openHAB/Resources/nb.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/nb.lproj/InfoPlist.strings +++ b/openHAB/Resources/nb.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/nl.lproj/InfoPlist.strings b/openHAB/Resources/nl.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/nl.lproj/InfoPlist.strings +++ b/openHAB/Resources/nl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/nl.lproj/Localizable.strings b/openHAB/Resources/nl.lproj/Localizable.strings index f2ccd2222..d45bd91ca 100644 --- a/openHAB/Resources/nl.lproj/Localizable.strings +++ b/openHAB/Resources/nl.lproj/Localizable.strings @@ -1,58 +1,58 @@ -"certficate_exists" = "Certificate already exists in the keychain."; -"message_not_decoded" = "Message could not be decoded"; -"notification" = "Notification"; -"dismiss" = "Dismiss"; -"search_items" = "Search openHAB items"; -"error" = "Error"; -"ssl_certificate_error" = "SSL Certificate Error"; -"empty_sitemap" = "openHAB returned empty sitemap list"; -"connecting" = "Connecting"; -"ssl_certificate_warning" = "SSL Certificate Warning"; -"unable_to_decode_certificate" = "Unable to decode certificate: %@."; -"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; -"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; -"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; -"abort" = "Abort"; -"once" = "Once"; -"always" = "Always"; -"certificate_import_title" = "Client Certificate Import"; -"certificate_import_text" = "Import client certificate into the keychain?"; -"certificate_import_password" = "Password required for import."; -"okay" = "Okay"; -"cancel" = "Cancel"; -"password" = "Password"; -"copy_label" = "Copy item label"; -"network_not_available" = "Network is not available."; -"connecting_local" = "Connecting to local URL"; -"remote_url_not_configured" = "Remote URL is not configured."; -"connecting_discovered" = "Connecting to discovered URL"; -"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; -"discovering_oh" = "Discovering openHAB"; -"settings_not_received" = "Settings not yet received from phone."; -"retry" = "Retry"; -"warning" = "Warning"; -"version" = "Version"; -"active_url" = "Active URL"; -"local_url" = "Local URL"; -"remote_url" = "Remote URL"; +"certficate_exists" = "Certificaat bestaat al in de sleutelhanger."; +"message_not_decoded" = "Bericht kon niet gedecodeerd worden"; +"notification" = "Notificatie"; +"dismiss" = "Afwijzen"; +"search_items" = "Zoek openHAB items"; +"error" = "Fout"; +"ssl_certificate_error" = "SSL-certificaat fout"; +"empty_sitemap" = "openHAB heeft een lege Sitemap geladen"; +"connecting" = "Verbinden"; +"ssl_certificate_warning" = "SSL-certificaat waarschuwing"; +"unable_to_decode_certificate" = "Kan certificaat niet decoderen: %@."; +"unable_to_add_certificate" = "Kan certificaat niet toevoegen aan de sleutelhanger: %@."; +"ssl_certificate_invalid" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ is ongeldig. Wilt u toch doorgaan?"; +"ssl_certificate_no_match" = "SSL-certificaat gepresenteerd door %1$@ voor %2$@ komt niet overeen met het record. Wilt u toch doorgaan?"; +"abort" = "Afbreken"; +"once" = "Eenmalig"; +"always" = "Altijd"; +"certificate_import_title" = "Cliëntcertificaat Importeren"; +"certificate_import_text" = "Client-certificaat in de sleutelhanger importeren?"; +"certificate_import_password" = "Wachtwoord vereist voor import."; +"okay" = "Oké"; +"cancel" = "Annuleer"; +"password" = "Wachtwoord"; +"copy_label" = "Item label kopiëren"; +"network_not_available" = "Netwerk is niet beschikbaar."; +"connecting_local" = "Verbinden naar lokale URL"; +"remote_url_not_configured" = "Externe URL is niet geconfigureerd."; +"connecting_discovered" = "Verbinden naar gevonden URL"; +"running_demo_mode" = "Uitvoeren in demo-modus. Controleer instellingen om demomodus uit te schakelen."; +"discovering_oh" = "Bezig met zoeken naar openHAB"; +"settings_not_received" = "Instellingen nog niet ontvangen van telefoon."; +"retry" = "Opnieuw"; +"warning" = "Waarschuwing"; +"version" = "Versie"; +"active_url" = "Actieve URL"; +"local_url" = "Lokale URL"; +"remote_url" = "Externe URL"; "sitemap" = "Sitemap"; -"username" = "Username"; -"sync_prefs" = "Sync preferences"; -"demo_mode" = "Demo mode"; -"always_send_credentials" = "Always send credentials"; -"ignore_ssl_certificates" = "Ignore SSL Certificates"; -"client_certificates" = "Client Certificates"; -"disable_idle_timeout" = "Disable Idle Timeout"; -"real_time_sliders" = "Real-time Sliders"; -"clear_image_cache" = "Clear Image Cache"; -"icon_type" = "Icon Type"; +"username" = "Gebruikersnaam"; +"sync_prefs" = "Synchronisatie voorkeuren"; +"demo_mode" = "Demomodus"; +"always_send_credentials" = "Altijd inloggegevens versturen"; +"ignore_ssl_certificates" = "Negeer SSL-certificaten"; +"client_certificates" = "Cliëntcertificaat"; +"disable_idle_timeout" = "Schermtimeout uitschakelen"; +"real_time_sliders" = "Realtime schuifregelaars"; +"clear_image_cache" = "Leeg de afbeeldingencache"; +"icon_type" = "Icoontype"; "info" = "Info"; -"select_sitemap" = "Select Sitemap"; -"crash_reporting" = "Crash Reporting"; -"legal" = "Legal"; -"openhab_connection" = "openHAB Connection"; -"application_settings" = "Application Settings"; -"app_version" = "App Version"; -"oh_version" = "openHAB Version"; +"select_sitemap" = "Selecteer Sitemap"; +"crash_reporting" = "Foutenrapportering"; +"legal" = "Juridisch"; +"openhab_connection" = "openHAB Verbinding"; +"application_settings" = "Applicatie Instellingen"; +"app_version" = "App Versie"; +"oh_version" = "openHAB Versie"; "oh_uuid" = "openHAB UUID"; -"oh_secret" = "openHAB Secret"; +"oh_secret" = "openHAB geheim"; diff --git a/openHAB/Resources/pl.lproj/InfoPlist.strings b/openHAB/Resources/pl.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/pl.lproj/InfoPlist.strings +++ b/openHAB/Resources/pl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/ro.lproj/InfoPlist.strings b/openHAB/Resources/ro.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/ro.lproj/InfoPlist.strings +++ b/openHAB/Resources/ro.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/ru.lproj/InfoPlist.strings b/openHAB/Resources/ru.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/ru.lproj/InfoPlist.strings +++ b/openHAB/Resources/ru.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/sr.lproj/InfoPlist.strings b/openHAB/Resources/sr.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/sr.lproj/InfoPlist.strings +++ b/openHAB/Resources/sr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings +++ b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/tr.lproj/InfoPlist.strings b/openHAB/Resources/tr.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/tr.lproj/InfoPlist.strings +++ b/openHAB/Resources/tr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/openHAB/Resources/uk.lproj/InfoPlist.strings b/openHAB/Resources/uk.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/uk.lproj/InfoPlist.strings +++ b/openHAB/Resources/uk.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + From 348b0686246bcf7744eac17af811bff808781d41 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 09:35:40 +0200 Subject: [PATCH 42/78] update crowdin fastlane integration --- fastlane/Fastfile | 5 +- openHAB/Resources/crowdinfiles.yml | 83 ++++++++++++++----- openHAB/Resources/cs.lproj/InfoPlist.strings | 2 - openHAB/Resources/da.lproj/InfoPlist.strings | 2 - openHAB/Resources/de.lproj/InfoPlist.strings | 2 - openHAB/Resources/el.lproj/InfoPlist.strings | 2 - openHAB/Resources/en.lproj/InfoPlist.strings | 2 - openHAB/Resources/es.lproj/InfoPlist.strings | 2 - openHAB/Resources/fi.lproj/InfoPlist.strings | 2 - openHAB/Resources/fr.lproj/InfoPlist.strings | 2 - openHAB/Resources/hu.lproj/InfoPlist.strings | 2 - openHAB/Resources/it.lproj/InfoPlist.strings | 2 - openHAB/Resources/nb.lproj/InfoPlist.strings | 2 - openHAB/Resources/nl.lproj/InfoPlist.strings | 2 - openHAB/Resources/pl.lproj/InfoPlist.strings | 2 - .../Resources/pt-BR.lproj/InfoPlist.strings | 2 - .../Resources/pt-PT.lproj/InfoPlist.strings | 2 - openHAB/Resources/ro.lproj/InfoPlist.strings | 2 - openHAB/Resources/ru.lproj/InfoPlist.strings | 2 - openHAB/Resources/sr.lproj/InfoPlist.strings | 2 - .../Resources/sv-SE.lproj/InfoPlist.strings | 2 - openHAB/Resources/tr.lproj/InfoPlist.strings | 2 - openHAB/Resources/uk.lproj/InfoPlist.strings | 2 - 23 files changed, 66 insertions(+), 64 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4ef4c8d37..f2fcb7b4e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -145,7 +145,7 @@ platform :ios do langs = config['langs'] # Expected size of the array, used to check if new languages have been added or not # The size logic can be omitted if needed - size = 63 + size = 65 response = Net::HTTP.get_response(URI(build)) if response.is_a? Net::HTTPSuccess @@ -163,8 +163,9 @@ platform :ios do # Key found, pull content and write to file langs[entry.name].each do |lang| + #puts File.basename("#{entry}") content = entry.get_input_stream.read - full_path = path + lang + '/Localizable.strings' + full_path = path + lang + '/' + File.basename("#{entry}") puts "Updated! \u{1F4AA} " + full_path File.open(full_path, 'w') { |file| file.write(content) } end diff --git a/openHAB/Resources/crowdinfiles.yml b/openHAB/Resources/crowdinfiles.yml index 31ac5be80..014d6efef 100644 --- a/openHAB/Resources/crowdinfiles.yml +++ b/openHAB/Resources/crowdinfiles.yml @@ -1,42 +1,85 @@ langs: - develop/openHAB/Resources/en.lproj/Localizable.strings: + openHAB/Resources/en.lproj/Localizable.strings: - en.lproj - develop/openHAB/Resources/de.lproj/Localizable.strings: + openHAB/Resources/de.lproj/Localizable.strings: - de.lproj - develop/openHAB/Resources/es.lproj/Localizable.strings: + openHAB/Resources/es.lproj/Localizable.strings: - es.lproj - develop/openHAB/Resources/it.lproj/Localizable.strings: + openHAB/Resources/it.lproj/Localizable.strings: - it.lproj - develop/openHAB/Resources/cs.lproj/Localizable.strings: + openHAB/Resources/cs.lproj/Localizable.strings: - cs.lproj - develop/openHAB/Resources/da.lproj/Localizable.strings: + openHAB/Resources/da.lproj/Localizable.strings: - da.lproj - develop/openHAB/Resources/el.lproj/Localizable.strings: + openHAB/Resources/el.lproj/Localizable.strings: - el.lproj - develop/openHAB/Resources/fi.lproj/Localizable.strings: + openHAB/Resources/fi.lproj/Localizable.strings: - fi.lproj - develop/openHAB/Resources/fr.lproj/Localizable.strings: + openHAB/Resources/fr.lproj/Localizable.strings: - fr.lproj - develop/openHAB/Resources/hu.lproj/Localizable.strings: + openHAB/Resources/hu.lproj/Localizable.strings: - hu.lproj - develop/openHAB/Resources/nl.lproj/Localizable.strings: + openHAB/Resources/nl.lproj/Localizable.strings: - nl.lproj - develop/openHAB/Resources/nb.lproj/Localizable.strings: + openHAB/Resources/nb.lproj/Localizable.strings: - nb.lproj - develop/openHAB/Resources/pl.lproj/Localizable.strings: + openHAB/Resources/pl.lproj/Localizable.strings: - pl.lproj - develop/openHAB/Resources/pt.lproj/Localizable.strings: + openHAB/Resources/pt.lproj/Localizable.strings: - pt-PT.lproj + openHAB/Resources/pt_BR.lproj/Localizable.strings: - pt-BR.lproj - develop/openHAB/Resources/ro.lproj/Localizable.strings: + openHAB/Resources/ro.lproj/Localizable.strings: - ro.lproj - develop/openHAB/Resources/ru.lproj/Localizable.strings: + openHAB/Resources/ru.lproj/Localizable.strings: - ru.lproj - develop/openHAB/Resources/sr.lproj/Localizable.strings: + openHAB/Resources/sr.lproj/Localizable.strings: - sr.lproj - develop/openHAB/Resources/sv.lproj/Localizable.strings: + openHAB/Resources/sv.lproj/Localizable.strings: - sv-SE.lproj - develop/openHAB/Resources/tr.lproj/Localizable.strings: + openHAB/Resources/tr.lproj/Localizable.strings: - tr.lproj - develop/openHAB/Resources/uk.lproj/Localizable.strings: + openHAB/Resources/uk.lproj/Localizable.strings: + - uk.lproj + openHAB/Resources/en.lproj/InfoPlist.strings: + - en.lproj + openHAB/Resources/de.lproj/InfoPlist.strings: + - de.lproj + openHAB/Resources/es.lproj/InfoPlist.strings: + - es.lproj + openHAB/Resources/it.lproj/InfoPlist.strings: + - it.lproj + openHAB/Resources/cs.lproj/InfoPlist.strings: + - cs.lproj + openHAB/Resources/da.lproj/InfoPlist.strings: + - da.lproj + openHAB/Resources/el.lproj/InfoPlist.strings: + - el.lproj + openHAB/Resources/fi.lproj/InfoPlist.strings: + - fi.lproj + openHAB/Resources/fr.lproj/InfoPlist.strings: + - fr.lproj + openHAB/Resources/hu.lproj/InfoPlist.strings: + - hu.lproj + openHAB/Resources/nl.lproj/InfoPlist.strings: + - nl.lproj + openHAB/Resources/nb.lproj/InfoPlist.strings: + - nb.lproj + openHAB/Resources/pl.lproj/InfoPlist.strings: + - pl.lproj + openHAB/Resources/pt.lproj/InfoPlist.strings: + - pt-PT.lproj + openHAB/Resources/pt_BR.lproj/InfoPlist.strings: + - pt-BR.lproj + openHAB/Resources/ro.lproj/InfoPlist.strings: + - ro.lproj + openHAB/Resources/ru.lproj/InfoPlist.strings: + - ru.lproj + openHAB/Resources/sr.lproj/InfoPlist.strings: + - sr.lproj + openHAB/Resources/sv.lproj/InfoPlist.strings: + - sv-SE.lproj + openHAB/Resources/tr.lproj/InfoPlist.strings: + - tr.lproj + openHAB/Resources/uk.lproj/InfoPlist.strings: - uk.lproj diff --git a/openHAB/Resources/cs.lproj/InfoPlist.strings b/openHAB/Resources/cs.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/cs.lproj/InfoPlist.strings +++ b/openHAB/Resources/cs.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/da.lproj/InfoPlist.strings b/openHAB/Resources/da.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/da.lproj/InfoPlist.strings +++ b/openHAB/Resources/da.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/de.lproj/InfoPlist.strings b/openHAB/Resources/de.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/de.lproj/InfoPlist.strings +++ b/openHAB/Resources/de.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/el.lproj/InfoPlist.strings b/openHAB/Resources/el.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/el.lproj/InfoPlist.strings +++ b/openHAB/Resources/el.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/es.lproj/InfoPlist.strings b/openHAB/Resources/es.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/es.lproj/InfoPlist.strings +++ b/openHAB/Resources/es.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/fi.lproj/InfoPlist.strings b/openHAB/Resources/fi.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/fi.lproj/InfoPlist.strings +++ b/openHAB/Resources/fi.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/fr.lproj/InfoPlist.strings b/openHAB/Resources/fr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/fr.lproj/InfoPlist.strings +++ b/openHAB/Resources/fr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/hu.lproj/InfoPlist.strings b/openHAB/Resources/hu.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/hu.lproj/InfoPlist.strings +++ b/openHAB/Resources/hu.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/it.lproj/InfoPlist.strings b/openHAB/Resources/it.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/it.lproj/InfoPlist.strings +++ b/openHAB/Resources/it.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/nb.lproj/InfoPlist.strings b/openHAB/Resources/nb.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/nb.lproj/InfoPlist.strings +++ b/openHAB/Resources/nb.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/nl.lproj/InfoPlist.strings b/openHAB/Resources/nl.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/nl.lproj/InfoPlist.strings +++ b/openHAB/Resources/nl.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/pl.lproj/InfoPlist.strings b/openHAB/Resources/pl.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pl.lproj/InfoPlist.strings +++ b/openHAB/Resources/pl.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pt-BR.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-BR.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/pt-PT.lproj/InfoPlist.strings +++ b/openHAB/Resources/pt-PT.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/ro.lproj/InfoPlist.strings b/openHAB/Resources/ro.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/ro.lproj/InfoPlist.strings +++ b/openHAB/Resources/ro.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/ru.lproj/InfoPlist.strings b/openHAB/Resources/ru.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/ru.lproj/InfoPlist.strings +++ b/openHAB/Resources/ru.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/sr.lproj/InfoPlist.strings b/openHAB/Resources/sr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/sr.lproj/InfoPlist.strings +++ b/openHAB/Resources/sr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/sv-SE.lproj/InfoPlist.strings +++ b/openHAB/Resources/sv-SE.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/tr.lproj/InfoPlist.strings b/openHAB/Resources/tr.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/tr.lproj/InfoPlist.strings +++ b/openHAB/Resources/tr.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/uk.lproj/InfoPlist.strings b/openHAB/Resources/uk.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/uk.lproj/InfoPlist.strings +++ b/openHAB/Resources/uk.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - From f6dfb8f5d73ae848c42a367d5e083ec5d1d92d6f Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 09:43:50 +0200 Subject: [PATCH 43/78] revert InfoPlist.strings --- openHAB/Resources/en.lproj/InfoPlist.strings | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index e69de29bb..477b28ff8 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + From d33a67dad2548bae9789c680a5a548e5ba6978d1 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 26 Aug 2020 09:50:45 +0200 Subject: [PATCH 44/78] update crowdin fastlane integration --- fastlane/Fastfile | 2 +- openHAB/Resources/crowdinfiles.yml | 84 +++++++++++++++--------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index f2fcb7b4e..851a6aee8 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -145,7 +145,7 @@ platform :ios do langs = config['langs'] # Expected size of the array, used to check if new languages have been added or not # The size logic can be omitted if needed - size = 65 + size = 66 response = Net::HTTP.get_response(URI(build)) if response.is_a? Net::HTTPSuccess diff --git a/openHAB/Resources/crowdinfiles.yml b/openHAB/Resources/crowdinfiles.yml index 014d6efef..0104b5ae4 100644 --- a/openHAB/Resources/crowdinfiles.yml +++ b/openHAB/Resources/crowdinfiles.yml @@ -1,85 +1,85 @@ langs: - openHAB/Resources/en.lproj/Localizable.strings: + develop/develop/openHAB/Resources/en.lproj/Localizable.strings: - en.lproj - openHAB/Resources/de.lproj/Localizable.strings: + develop/openHAB/Resources/de.lproj/Localizable.strings: - de.lproj - openHAB/Resources/es.lproj/Localizable.strings: + develop/openHAB/Resources/es.lproj/Localizable.strings: - es.lproj - openHAB/Resources/it.lproj/Localizable.strings: + develop/openHAB/Resources/it.lproj/Localizable.strings: - it.lproj - openHAB/Resources/cs.lproj/Localizable.strings: + develop/openHAB/Resources/cs.lproj/Localizable.strings: - cs.lproj - openHAB/Resources/da.lproj/Localizable.strings: + develop/openHAB/Resources/da.lproj/Localizable.strings: - da.lproj - openHAB/Resources/el.lproj/Localizable.strings: + develop/openHAB/Resources/el.lproj/Localizable.strings: - el.lproj - openHAB/Resources/fi.lproj/Localizable.strings: + develop/openHAB/Resources/fi.lproj/Localizable.strings: - fi.lproj - openHAB/Resources/fr.lproj/Localizable.strings: + develop/openHAB/Resources/fr.lproj/Localizable.strings: - fr.lproj - openHAB/Resources/hu.lproj/Localizable.strings: + develop/openHAB/Resources/hu.lproj/Localizable.strings: - hu.lproj - openHAB/Resources/nl.lproj/Localizable.strings: + develop/openHAB/Resources/nl.lproj/Localizable.strings: - nl.lproj - openHAB/Resources/nb.lproj/Localizable.strings: + develop/openHAB/Resources/nb.lproj/Localizable.strings: - nb.lproj - openHAB/Resources/pl.lproj/Localizable.strings: + develop/openHAB/Resources/pl.lproj/Localizable.strings: - pl.lproj - openHAB/Resources/pt.lproj/Localizable.strings: + develop/openHAB/Resources/pt.lproj/Localizable.strings: - pt-PT.lproj - openHAB/Resources/pt_BR.lproj/Localizable.strings: + develop/openHAB/Resources/pt_BR.lproj/Localizable.strings: - pt-BR.lproj - openHAB/Resources/ro.lproj/Localizable.strings: + develop/openHAB/Resources/ro.lproj/Localizable.strings: - ro.lproj - openHAB/Resources/ru.lproj/Localizable.strings: + develop/openHAB/Resources/ru.lproj/Localizable.strings: - ru.lproj - openHAB/Resources/sr.lproj/Localizable.strings: + develop/openHAB/Resources/sr.lproj/Localizable.strings: - sr.lproj - openHAB/Resources/sv.lproj/Localizable.strings: + develop/openHAB/Resources/sv.lproj/Localizable.strings: - sv-SE.lproj - openHAB/Resources/tr.lproj/Localizable.strings: + develop/openHAB/Resources/tr.lproj/Localizable.strings: - tr.lproj - openHAB/Resources/uk.lproj/Localizable.strings: + develop/openHAB/Resources/uk.lproj/Localizable.strings: - uk.lproj - openHAB/Resources/en.lproj/InfoPlist.strings: + develop/openHAB/Resources/en.lproj/InfoPlist.strings: - en.lproj - openHAB/Resources/de.lproj/InfoPlist.strings: + develop/openHAB/Resources/de.lproj/InfoPlist.strings: - de.lproj - openHAB/Resources/es.lproj/InfoPlist.strings: + develop/openHAB/Resources/es.lproj/InfoPlist.strings: - es.lproj - openHAB/Resources/it.lproj/InfoPlist.strings: + develop/openHAB/Resources/it.lproj/InfoPlist.strings: - it.lproj - openHAB/Resources/cs.lproj/InfoPlist.strings: + develop/openHAB/Resources/cs.lproj/InfoPlist.strings: - cs.lproj - openHAB/Resources/da.lproj/InfoPlist.strings: + develop/openHAB/Resources/da.lproj/InfoPlist.strings: - da.lproj - openHAB/Resources/el.lproj/InfoPlist.strings: + develop/openHAB/Resources/el.lproj/InfoPlist.strings: - el.lproj - openHAB/Resources/fi.lproj/InfoPlist.strings: + develop/openHAB/Resources/fi.lproj/InfoPlist.strings: - fi.lproj - openHAB/Resources/fr.lproj/InfoPlist.strings: + develop/openHAB/Resources/fr.lproj/InfoPlist.strings: - fr.lproj - openHAB/Resources/hu.lproj/InfoPlist.strings: + develop/openHAB/Resources/hu.lproj/InfoPlist.strings: - hu.lproj - openHAB/Resources/nl.lproj/InfoPlist.strings: + develop/openHAB/Resources/nl.lproj/InfoPlist.strings: - nl.lproj - openHAB/Resources/nb.lproj/InfoPlist.strings: + develop/openHAB/Resources/nb.lproj/InfoPlist.strings: - nb.lproj - openHAB/Resources/pl.lproj/InfoPlist.strings: + develop/openHAB/Resources/pl.lproj/InfoPlist.strings: - pl.lproj - openHAB/Resources/pt.lproj/InfoPlist.strings: + develop/openHAB/Resources/pt.lproj/InfoPlist.strings: - pt-PT.lproj - openHAB/Resources/pt_BR.lproj/InfoPlist.strings: + develop/openHAB/Resources/pt_BR.lproj/InfoPlist.strings: - pt-BR.lproj - openHAB/Resources/ro.lproj/InfoPlist.strings: + develop/openHAB/Resources/ro.lproj/InfoPlist.strings: - ro.lproj - openHAB/Resources/ru.lproj/InfoPlist.strings: + develop/openHAB/Resources/ru.lproj/InfoPlist.strings: - ru.lproj - openHAB/Resources/sr.lproj/InfoPlist.strings: + develop/openHAB/Resources/sr.lproj/InfoPlist.strings: - sr.lproj - openHAB/Resources/sv.lproj/InfoPlist.strings: + develop/openHAB/Resources/sv.lproj/InfoPlist.strings: - sv-SE.lproj - openHAB/Resources/tr.lproj/InfoPlist.strings: + develop/openHAB/Resources/tr.lproj/InfoPlist.strings: - tr.lproj - openHAB/Resources/uk.lproj/InfoPlist.strings: + develop/openHAB/Resources/uk.lproj/InfoPlist.strings: - uk.lproj From 693a248f46f49080e51607b3bcf6b4908f168a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Thu, 27 Aug 2020 10:01:35 +0200 Subject: [PATCH 45/78] Fix for #572 --- openHAB/SliderUITableViewCell.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openHAB/SliderUITableViewCell.swift b/openHAB/SliderUITableViewCell.swift index 09aea976b..64b39b687 100644 --- a/openHAB/SliderUITableViewCell.swift +++ b/openHAB/SliderUITableViewCell.swift @@ -112,6 +112,8 @@ class SliderUITableViewCell: GenericUITableViewCell { widgetSlider?.minimumValue = Float(widget.minValue) widgetSlider?.maximumValue = Float(widget.maxValue) let widgetValue = adjustedValue() + widgetSlider?.value = Float(widgetValue) + step = Float(widget.step) // if there is a formatted value in widget label, take it. Otherwise display local value From 11673974c9c8af8d31a03cfd973488f688310e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Thu, 27 Aug 2020 10:03:15 +0200 Subject: [PATCH 46/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 032f34dd8..0ead87f84 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1872,7 +1872,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1884,7 +1884,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1916,7 +1916,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1928,7 +1928,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -1957,7 +1957,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -1976,7 +1976,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2005,7 +2005,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2053,7 +2053,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2071,7 +2071,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2103,7 +2103,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2120,7 +2120,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2151,14 +2151,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2190,14 +2190,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2226,7 +2226,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2238,7 +2238,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2268,7 +2268,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2280,7 +2280,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2310,7 +2310,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2322,7 +2322,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2355,7 +2355,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2367,7 +2367,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2508,7 +2508,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2525,7 +2525,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2555,7 +2555,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410450; + CURRENT_PROJECT_VERSION = 1580410451; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2572,7 +2572,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.4.2; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From adb02375281073f9338e39a0f68a1b2a5e60ef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 08:37:42 +0200 Subject: [PATCH 47/78] Fix for bug introduced by merging. Introduced brackets at the wrong place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/OpenHABViewController.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 980706be0..b08ea27ed 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -518,11 +518,12 @@ class OpenHABViewController: UIViewController { } } } - self.currentPageOperation?.resume() - - os_log("OpenHABViewController request sent", log: .remoteAccess, type: .error) } } + + currentPageOperation?.resume() + + os_log("OpenHABViewController request sent", log: .remoteAccess, type: .error) } // Select sitemap From 8d1006e69857067c5fffb5ba608daa90c4e624a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 16:06:12 +0200 Subject: [PATCH 48/78] Update to cocoapod 1.10.0beta2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index 1a9b395f2..53a4aecef 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -168,4 +168,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ba32ee2afd2062b9d8b4772a91878dd85b5a8245 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.0.beta.2 From 06acacd6aedfbac5cc051675dd9c73f3af3e11bf Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Fri, 28 Aug 2020 16:08:49 +0200 Subject: [PATCH 49/78] Handling of UoM (#555) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * First attempt with pocketsvg Signed-off-by: Tim Müller-Seydlitz * Committing before moving away * Introduced enums ItemType/WidgetType to OpenHABItem.type, OpenHABItem.groupType, OpenHABWidget.type Introduced NumberState to hold value, unit and format Inspired by kotlin app Extended parsing of JSON properties to complete feature set and for instance handle visibility, switchSupport (tbd) Error correction: minimumFractionDigits in valueText Fix for #554 (to be extended beyond Setpoint) Signed-off-by: Tim Müller-Seydlitz * Update openHAB/SetpointUITableViewCell.swift Co-authored-by: weakfl * Update openHABCore/Sources/Util/StringExtension.swift Co-authored-by: weakfl * Update openHABCore/Sources/Util/StringExtension.swift Co-authored-by: weakfl * Removed commented code in OpenHABViewController.swift Encapsulated unit, format to private(set) Signed-off-by: Tim Müller-Seydlitz * Upgrading cocoapod to suppress more warnings Signed-off-by: Tim Müller-Seydlitz * Moved ItemType/WidgetType to separate file ItemType.swift Taking advantage of enum with raw value of String to be Decodable while graciously handling of unknown enum types Signed-off-by: Tim Müller-Seydlitz * Fix for #552: Incorrect OnOff icon state for Color Items Signed-off-by: Tim Müller-Seydlitz * Committed version bump * Fix for #552: Setting icon state - with logic from kotlin app Signed-off-by: Tim Müller-Seydlitz * Committed version bump * Reworked dequeueReusableCell in OpenHABViewController to higher level of abstraction Nested enums for WidgetType and ItemType into OpenHABWidget/OpenHABItem respectively (cleanup of UnknownCaseRepresentable) UIColor.black instead of hue=saturation=brightness=0 Aligning SwiftUI struct for Setpoint to UoM handling Signed-off-by: Tim Müller-Seydlitz * Replacing a != "" by !a.isEmpty Replacing (a?.count ?? 0) > 0 by !(a ?? "").isEmpty Decoding OpenHABServerProperties Handling of sliders of type color Detecting server version on /rest instead of /rest/bindings - Addressing #526 Renaming UserDefault to UserDefaultsBacked watchOS: though pathMonitor is accessible in watchOS it is ignored Signed-off-by: Tim Müller-Seydlitz * minimumFractionDigits only once Signed-off-by: Tim Müller-Seydlitz * Preparing release Signed-off-by: Tim Müller-Seydlitz * Committed version bump * Changing version number to 2.4.0 Signed-off-by: Tim Müller-Seydlitz * Committed version bump * Fix for #572 * Committed version bump * Fix for bug introduced by merging. Introduced brackets at the wrong place Signed-off-by: Tim Müller-Seydlitz Co-authored-by: weakfl --- .swiftformat | 3 +- Podfile | 4 +- Podfile.lock | 158 +++++----- openHAB.xcodeproj/project.pbxproj | 88 ++++-- .../xcshareddata/xcschemes/openHAB.xcscheme | 11 +- .../xcschemes/openHABTestsSwift.xcscheme | 2 +- .../xcschemes/openHABUITests.xcscheme | 11 +- .../openHABWatch (Notification).xcscheme | 31 +- .../xcschemes/openHABWatch.xcscheme | 27 +- .../openHABWatchSwift (Complication).xcscheme | 27 +- openHAB/AppDelegate.swift | 2 +- openHAB/GenericUITableViewCell.swift | 4 +- openHAB/NewImageUITableViewCell.swift | 14 +- .../OpenHABDrawerTableViewController.swift | 2 +- .../OpenHABNotificationsViewController.swift | 2 +- openHAB/OpenHABTracker.swift | 2 +- openHAB/OpenHABViewController.swift | 270 ++++++++++-------- openHAB/ScaleAspectFitImageView.swift | 10 +- openHAB/SetpointUITableViewCell.swift | 56 ++-- openHAB/SliderUITableViewCell.swift | 46 ++- openHAB/SwitchUITableViewCell.swift | 3 +- openHAB/openHAB-Info.plist | 4 +- openHABCore/Sources/Model/NumberState.swift | 50 ++++ openHABCore/Sources/Model/OpenHABItem.swift | 105 +++++-- .../Model/OpenHABServerProperties.swift | 34 +++ .../Sources/Model/OpenHABSitemapPage.swift | 2 +- .../Model/OpenHABStateDescription.swift | 24 +- openHABCore/Sources/Model/OpenHABWidget.swift | 109 ++++++- openHABCore/Sources/Util/Endpoint.swift | 8 +- openHABCore/Sources/Util/Preferences.swift | 31 +- .../Sources/Util/StringExtension.swift | 70 +++++ .../Sources/Util/UIColorExtension.swift | 25 ++ .../Util/UnknownCaseRepresentable.swift | 24 ++ openHABTestsSwift/NumberStateTest.swift | 90 ++++++ openHABTestsSwift/OpenHABGeneralTests.swift | 2 +- .../OpenHABJSONParserTests.swift | 25 +- openHABTestsSwift/OpenHABXMLParserTests.swift | 5 +- openHABTestsSwift/ParseAsTest.swift | 33 +++ openHABTestsSwift/restAPI.json | 31 ++ .../OpenHABWatchTracker.swift | 41 ++- .../PreferencesHostingController.swift | 1 + .../Views/ContentView.swift | 8 +- .../Views/Rows/GenericRow.swift | 2 +- .../Views/Rows/ImageRawRow.swift | 2 +- .../Views/Rows/ImageRow.swift | 2 +- .../Views/Rows/SegmentRow.swift | 2 +- .../Views/Rows/SetpointRow.swift | 53 ++-- .../Views/Rows/SliderRow.swift | 8 +- .../Views/Rows/SwitchRow.swift | 2 +- .../Views/Utils/DetailTextLabelView.swift | 2 +- .../Views/Utils/IconView.swift | 2 +- .../Views/Utils/TextLabelView.swift | 2 +- .../Model/ObservableOpenHABDataObject.swift | 40 +-- .../Model/ObservableOpenHABSitemapPage.swift | 2 +- .../Model/ObservableOpenHABWidget.swift | 51 +++- .../Model/UserDefaultsBacked.swift | 36 +++ .../openHABWatch Extension/UserData.swift | 127 ++++---- .../external/AppMessageService.swift | 2 +- 58 files changed, 1199 insertions(+), 631 deletions(-) create mode 100644 openHABCore/Sources/Model/NumberState.swift create mode 100644 openHABCore/Sources/Model/OpenHABServerProperties.swift create mode 100644 openHABCore/Sources/Util/UnknownCaseRepresentable.swift create mode 100644 openHABTestsSwift/NumberStateTest.swift create mode 100644 openHABTestsSwift/ParseAsTest.swift create mode 100644 openHABTestsSwift/restAPI.json create mode 100644 openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift diff --git a/.swiftformat b/.swiftformat index e3bb8df7b..7045766d2 100644 --- a/.swiftformat +++ b/.swiftformat @@ -1,11 +1,12 @@ # file options ---swiftversion 5.1 +--swiftversion 5.2 --exclude Pods --symlinks ignore # disabled rules --disable specifiers # see https://github.com/nicklockwood/SwiftFormat/issues/364 --disable redundantParens +--disable wrapMultilineStatementBraces # opt-in rules --enable isEmpty diff --git a/Podfile b/Podfile index 23c057591..da4ac61f8 100644 --- a/Podfile +++ b/Podfile @@ -14,7 +14,7 @@ target 'openHAB' do shared_pods pod 'SwiftFormat/CLI' pod 'SwiftLint' - pod 'SVGKit' + pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '3.x' pod 'Fabric', '~> 1.7' pod 'Crashlytics', '~> 3.9' @@ -26,6 +26,8 @@ target 'openHAB' do pod 'DynamicButton', '~> 6.2' pod 'SideMenu', '~> 6.4' pod 'Kingfisher', '~> 5.0' + #pod "Macaw", "0.9.6" + #pod 'SwiftSVG', '~> 2.0' target 'openHABTestsSwift' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index 53a4aecef..638e64867 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,96 +1,91 @@ PODS: - Alamofire (4.9.1) - - CocoaLumberjack (3.6.1): - - CocoaLumberjack/Core (= 3.6.1) - - CocoaLumberjack/Core (3.6.1) + - CocoaLumberjack (3.6.2): + - CocoaLumberjack/Core (= 3.6.2) + - CocoaLumberjack/Core (3.6.2) - Crashlytics (3.14.0): - Fabric (~> 1.10.2) - DeviceKit (3.2.0) - DynamicButton (6.2.1) - Fabric (1.10.2) - - Firebase/Analytics (6.24.0): + - Firebase/Analytics (6.29.0): - Firebase/Core - - Firebase/Core (6.24.0): + - Firebase/Core (6.29.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.5.0) - - Firebase/CoreOnly (6.24.0): - - FirebaseCore (= 6.7.0) - - FirebaseAnalytics (6.5.0): - - FirebaseCore (~> 6.7) - - FirebaseInstallations (~> 1.2) - - GoogleAppMeasurement (= 6.5.0) - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" + - FirebaseAnalytics (= 6.7.0) + - Firebase/CoreOnly (6.29.0): + - FirebaseCore (= 6.9.2) + - FirebaseAnalytics (6.7.0): + - FirebaseCore (~> 6.8) + - FirebaseInstallations (~> 1.4) + - GoogleAppMeasurement (= 6.7.0) + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" - nanopb (~> 1.30905.0) - - FirebaseCore (6.7.0): + - FirebaseCore (6.9.2): - FirebaseCoreDiagnostics (~> 1.3) - - FirebaseCoreDiagnosticsInterop (~> 1.2) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) - - FirebaseCoreDiagnostics (1.3.0): - - FirebaseCoreDiagnosticsInterop (~> 1.2) - - GoogleDataTransportCCTSupport (~> 3.1) - - GoogleUtilities/Environment (~> 6.5) - - GoogleUtilities/Logger (~> 6.5) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) + - FirebaseCoreDiagnostics (1.5.0): + - GoogleDataTransport (~> 7.0) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) - nanopb (~> 1.30905.0) - - FirebaseCoreDiagnosticsInterop (1.2.0) - - FirebaseInstallations (1.2.0): - - FirebaseCore (~> 6.6) - - GoogleUtilities/Environment (~> 6.6) - - GoogleUtilities/UserDefaults (~> 6.6) + - FirebaseInstallations (1.5.0): + - FirebaseCore (~> 6.8) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/UserDefaults (~> 6.7) - PromisesObjC (~> 1.2) - FlexColorPicker (1.4.2) - Fuzi (3.1.2) - - GoogleAppMeasurement (6.5.0): - - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - - GoogleUtilities/MethodSwizzler (~> 6.0) - - GoogleUtilities/Network (~> 6.0) - - "GoogleUtilities/NSData+zlib (~> 6.0)" + - GoogleAppMeasurement (6.7.0): + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" - nanopb (~> 1.30905.0) - - GoogleDataTransport (6.1.0) - - GoogleDataTransportCCTSupport (3.1.0): - - GoogleDataTransport (~> 6.1) + - GoogleDataTransport (7.1.0): - nanopb (~> 1.30905.0) - - GoogleUtilities/AppDelegateSwizzler (6.6.0): + - GoogleUtilities/AppDelegateSwizzler (6.7.1): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.6.0): + - GoogleUtilities/Environment (6.7.1): - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.6.0): + - GoogleUtilities/Logger (6.7.1): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.6.0): + - GoogleUtilities/MethodSwizzler (6.7.1): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.6.0): + - GoogleUtilities/Network (6.7.1): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.6.0)" - - GoogleUtilities/Reachability (6.6.0): + - "GoogleUtilities/NSData+zlib (6.7.1)" + - GoogleUtilities/Reachability (6.7.1): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.6.0): + - GoogleUtilities/UserDefaults (6.7.1): - GoogleUtilities/Logger - - Kingfisher (5.13.4): - - Kingfisher/Core (= 5.13.4) - - Kingfisher/Core (5.13.4) - - Kingfisher/SwiftUI (5.13.4): + - Kingfisher (5.14.1): + - Kingfisher/Core (= 5.14.1) + - Kingfisher/Core (5.14.1) + - Kingfisher/SwiftUI (5.14.1): - Kingfisher/Core - nanopb (1.30905.0): - nanopb/decode (= 1.30905.0) - nanopb/encode (= 1.30905.0) - nanopb/decode (1.30905.0) - nanopb/encode (1.30905.0) - - PromisesObjC (1.2.8) - - SideMenu (6.4.8) - - SVGKit (2.1.1): + - PromisesObjC (1.2.9) + - SideMenu (6.4.9) + - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.44.9) + - SwiftFormat/CLI (0.45.2) - SwiftLint (0.39.2) - - SwiftMessages (7.0.1): - - SwiftMessages/App (= 7.0.1) - - SwiftMessages/App (7.0.1) + - SwiftMessages (8.0.0): + - SwiftMessages/App (= 8.0.0) + - SwiftMessages/App (8.0.0) DEPENDENCIES: - Alamofire (~> 4.0) @@ -104,7 +99,7 @@ DEPENDENCIES: - Kingfisher (~> 5.0) - Kingfisher/SwiftUI (~> 5.0) - SideMenu (~> 6.4) - - SVGKit + - SVGKit (from `https://github.com/SVGKit/SVGKit.git`, branch `3.x`) - SwiftFormat/CLI - SwiftLint - SwiftMessages @@ -121,51 +116,56 @@ SPEC REPOS: - FirebaseAnalytics - FirebaseCore - FirebaseCoreDiagnostics - - FirebaseCoreDiagnosticsInterop - FirebaseInstallations - FlexColorPicker - Fuzi - GoogleAppMeasurement - GoogleDataTransport - - GoogleDataTransportCCTSupport - GoogleUtilities - Kingfisher - nanopb - PromisesObjC - SideMenu - - SVGKit - SwiftFormat - SwiftLint - SwiftMessages +EXTERNAL SOURCES: + SVGKit: + :branch: 3.x + :git: https://github.com/SVGKit/SVGKit.git + +CHECKOUT OPTIONS: + SVGKit: + :commit: 9240977515c04053f8c96c9dfdb764dc7b98b9ba + :git: https://github.com/SVGKit/SVGKit.git + SPEC CHECKSUMS: Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 - CocoaLumberjack: b17ae15142558d08bbacf69775fa10c4abbebcc9 + CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94 Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df DeviceKit: d081659419cce07c0b5239dbc9fb39ed7413c7fe DynamicButton: 95f30460793bd3510a5c213ac1b810a5e3d54b6a Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 - Firebase: b28e55c60efd98963cd9011fe2fac5a10c2ba124 - FirebaseAnalytics: 7386fc2176e3f93ad8ef34b5b1f2b33a891e4962 - FirebaseCore: e610482f64097b0e9f056cd97bc6b33dfabcbb6a - FirebaseCoreDiagnostics: 4a773a47bd83bbd5a9b1ccf1ce7caa8b2d535e67 - FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850 - FirebaseInstallations: 2119fb3e46b0a88bfdbf12562f855ee3252462fa + Firebase: 57957c8d6eb3d8b80a560b1dc58be24724b89ff2 + FirebaseAnalytics: aa522dce9fd93002ba1554467d23ce7092323000 + FirebaseCore: 7930a1946517d94256d857f97371ed993b55f7bd + FirebaseCoreDiagnostics: 7535fe695737f8c5b350584292a70b7f8ff0357b + FirebaseInstallations: 3c520c951305cbf9ca54eb891ff9e6d1fd384881 FlexColorPicker: d7ed5cfd8ceb936f2930e4e30629f9448967a5f8 Fuzi: dba7215e52fb39dd7b1a62f69ede1e30edff0ae1 - GoogleAppMeasurement: 4c644d86835d827bab30ab6aabb9ecaf1f500735 - GoogleDataTransport: f6f8eba931df03ebd2232ff4645aa85f8f47b5ab - GoogleDataTransportCCTSupport: d70a561f7d236af529fee598835caad5e25f6d3d - GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 - Kingfisher: d2279a7abece3c7f25a80cd2b7f363ca5cf3f44c + GoogleAppMeasurement: 345d365fd105e6682bf5084783a5352a3db26820 + GoogleDataTransport: af0c79193dc59acd37630b4833d0dc6912ae6bd5 + GoogleUtilities: e121a3867449ce16b0e35ddf1797ea7a389ffdf2 + Kingfisher: 8050bc6f7f68cbf3908bd04df7ccbac188f6d6d6 nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 - PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6 - SideMenu: 4a891be552d30bb6fa87ad404d62e485f8450c34 - SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac - SwiftFormat: e415b539c50e7a956a44b023544c9846c0c037d7 + PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 + SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 + SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63 + SwiftFormat: 07a1794c1331daaefc1ca6c2ff1da38ee9ca090a SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 - SwiftMessages: b577dc7043be8b299857ab35bb663dbff6483bd0 + SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 -PODFILE CHECKSUM: ba32ee2afd2062b9d8b4772a91878dd85b5a8245 +PODFILE CHECKSUM: 7e3ab1cfad25c0c0ad6f55cd58134ce3b910ec2e COCOAPODS: 1.10.0.beta.2 diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 96ec3aa1c..d53b550db 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -100,8 +100,13 @@ DA15BFBD23C6726400BD8ADA /* ObservableOpenHABDataObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA15BFBC23C6726400BD8ADA /* ObservableOpenHABDataObject.swift */; }; DA19E25B22FD801D002F8F2F /* OpenHABGeneralTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA19E25A22FD801D002F8F2F /* OpenHABGeneralTests.swift */; }; DA1C32BA2311CCE200FACFB0 /* JSONData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1C32B92311CCE200FACFB0 /* JSONData.swift */; }; + DA1EAECF24E94871008A6B22 /* OpenHABServerProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */; }; + DA1EAED024E94871008A6B22 /* OpenHABServerProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */; }; DA21EAE22339621C001AB415 /* Throttler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21EAE12339621C001AB415 /* Throttler.swift */; }; DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA28C361225241DE00AB409C /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + DA2CBDAE24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */; }; + DA2CBDAF24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */; }; + DA2CBDB124D7562C003CAE8A /* ParseAsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */; }; DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */; }; DA2E0AA423DC96E9009B0A99 /* EncircledIconWithAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0AA323DC96E9009B0A99 /* EncircledIconWithAction.swift */; }; DA2E0B0E23DCC153009B0A99 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E0B0D23DCC152009B0A99 /* MapView.swift */; }; @@ -120,6 +125,7 @@ DA88F8C622EC377200B408E5 /* ReleaseNotes.md in Resources */ = {isa = PBXBuildFile; fileRef = DA88F8C522EC377100B408E5 /* ReleaseNotes.md */; }; DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA966477232EDEAD00CB418B /* MockURLProtocol.swift */; }; DA96647A232EE3C200CB418B /* RESTAPITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA966479232EE3C200CB418B /* RESTAPITest.swift */; }; + DA9721C324E29A8F0092CCFD /* UserDefaultsBacked.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */; }; DA97BB072329902100AAE470 /* LargeSitemap.json in Resources */ = {isa = PBXBuildFile; fileRef = DA97BB062329902000AAE470 /* LargeSitemap.json */; }; DAA42BA821DC97E000244B2A /* NotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA42BA721DC97DF00244B2A /* NotificationTableViewCell.swift */; }; DAA42BAA21DC983B00244B2A /* VideoUITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA42BA921DC983B00244B2A /* VideoUITableViewCell.swift */; }; @@ -131,6 +137,9 @@ DAC6608D236F771600F4501E /* PreferencesSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608C236F771600F4501E /* PreferencesSwiftUIView.swift */; }; DAC6608F236F80BA00F4501E /* PreferencesRowUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */; }; DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */; }; + DACC72E224D00D59007EFAE3 /* NumberStateTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */; }; + DADC1EAD24D2CB8B0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; + DADC1EAE24D2CB8C0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; DAE249A223EE07C800986877 /* Future.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE249A023EE07C800986877 /* Future.swift */; }; DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */; }; DAEAA89D21E6B06400267EA3 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89C21E6B06300267EA3 /* ReusableView.swift */; }; @@ -444,8 +453,11 @@ DA1C2E6D230DC28F00FACFB0 /* primary_category.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = primary_category.txt; sourceTree = ""; }; DA1C2E6E230DC28F00FACFB0 /* Snapfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Snapfile; sourceTree = ""; }; DA1C32B92311CCE200FACFB0 /* JSONData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONData.swift; sourceTree = ""; }; + DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABServerProperties.swift; sourceTree = ""; }; DA21EAE12339621C001AB415 /* Throttler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Throttler.swift; sourceTree = ""; }; DA28C361225241DE00AB409C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownCaseRepresentable.swift; sourceTree = ""; }; + DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAsTest.swift; sourceTree = ""; }; DA2DC22F21F2736C00830730 /* openHABTestsSwift.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = openHABTestsSwift.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA2DC23121F2736C00830730 /* OpenHABJSONParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABJSONParserTests.swift; sourceTree = ""; }; DA2DC23321F2736C00830730 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -466,6 +478,7 @@ DA88F8C522EC377100B408E5 /* ReleaseNotes.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = ReleaseNotes.md; sourceTree = ""; }; DA966477232EDEAD00CB418B /* MockURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockURLProtocol.swift; sourceTree = ""; }; DA966479232EE3C200CB418B /* RESTAPITest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTAPITest.swift; sourceTree = ""; }; + DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsBacked.swift; sourceTree = ""; }; DA97BB062329902000AAE470 /* LargeSitemap.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = LargeSitemap.json; sourceTree = ""; }; DAA42BA721DC97DF00244B2A /* NotificationTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationTableViewCell.swift; sourceTree = ""; }; DAA42BA921DC983B00244B2A /* VideoUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoUITableViewCell.swift; sourceTree = ""; }; @@ -478,6 +491,9 @@ DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesRowUIView.swift; sourceTree = ""; }; DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABWatchTests.swift; sourceTree = ""; }; DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCaseExtension.swift; sourceTree = ""; }; + DACC72E024CE14FB007EFAE3 /* restAPI.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = restAPI.json; sourceTree = ""; }; + DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberStateTest.swift; sourceTree = ""; }; + DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberState.swift; sourceTree = ""; }; DAE249A023EE07C800986877 /* Future.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Future.swift; path = openHABCore/Sources/Util/Future.swift; sourceTree = SOURCE_ROOT; }; DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABNotificationsViewController.swift; sourceTree = ""; }; DAEAA89C21E6B06300267EA3 /* ReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReusableView.swift; sourceTree = ""; }; @@ -727,6 +743,8 @@ 9350F16E23814F2500054BA8 /* OpenHABStateDescription.swift */, 9350F16823814EF500054BA8 /* OpenHABWidget.swift */, 9350F16B23814F0D00054BA8 /* OpenHABWidgetMapping.swift */, + DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */, + DA1EAECD24E9469E008A6B22 /* OpenHABServerProperties.swift */, ); path = Model; sourceTree = ""; @@ -737,6 +755,7 @@ DA15BFBC23C6726400BD8ADA /* ObservableOpenHABDataObject.swift */, 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */, 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */, + DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */, ); name = Model; path = "openHABWatch Extension/Model"; @@ -756,6 +775,7 @@ 9350F17B2381509300054BA8 /* OSLogExtension.swift */, 9350F1812381514E00054BA8 /* ServerCertificateManager.swift */, 9350F190238151CE00054BA8 /* StringExtension.swift */, + DA2CBDAD24D5FD73003CAE8A /* UnknownCaseRepresentable.swift */, 9350F193238151F100054BA8 /* Preferences.swift */, DAF4578323D780730018B495 /* UIColorExtension.swift */, 9394102522CB5CDB00EB4255 /* Collection+SafeAccess.swift */, @@ -876,6 +896,9 @@ DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */, DA2DC23321F2736C00830730 /* Info.plist */, DA966477232EDEAD00CB418B /* MockURLProtocol.swift */, + DACC72E024CE14FB007EFAE3 /* restAPI.json */, + DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */, + DA2CBDB024D7562C003CAE8A /* ParseAsTest.swift */, ); path = openHABTestsSwift; sourceTree = ""; @@ -1685,6 +1708,7 @@ 9350F16623814ED700054BA8 /* OpenHABSitemapPage.swift in Sources */, 9350F194238151F100054BA8 /* Preferences.swift in Sources */, 93F38C6C238034DA001B1451 /* DataObject.swift in Sources */, + DA1EAECF24E94871008A6B22 /* OpenHABServerProperties.swift in Sources */, 9350F16C23814F0D00054BA8 /* OpenHABWidgetMapping.swift in Sources */, 93F38D4B238037E3001B1451 /* OpenHABAccessTokenAdapter.swift in Sources */, DAB2438C23EF4E1F00C9C68E /* Future.swift in Sources */, @@ -1700,10 +1724,12 @@ 9350F1822381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579D23D904350018B495 /* UIColorExtension.swift in Sources */, 9350F16323814EC200054BA8 /* OpenHABSitemap.swift in Sources */, + DA2CBDAE24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */, 9350F10123814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10423814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F191238151CE00054BA8 /* StringExtension.swift in Sources */, 9350F18B2381519300054BA8 /* ClientCertificateManager.swift in Sources */, + DADC1EAD24D2CB8B0052B8D4 /* NumberState.swift in Sources */, 9350F1852381516300054BA8 /* KeyedDecodingContainerProtocolExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1717,6 +1743,7 @@ 9350F16723814ED700054BA8 /* OpenHABSitemapPage.swift in Sources */, 9350F195238151F100054BA8 /* Preferences.swift in Sources */, 93F38C6D238034DA001B1451 /* DataObject.swift in Sources */, + DA1EAED024E94871008A6B22 /* OpenHABServerProperties.swift in Sources */, 9350F16D23814F0D00054BA8 /* OpenHABWidgetMapping.swift in Sources */, 93F38D4C238037E3001B1451 /* OpenHABAccessTokenAdapter.swift in Sources */, DAE249A223EE07C800986877 /* Future.swift in Sources */, @@ -1732,10 +1759,12 @@ 9350F1832381514E00054BA8 /* ServerCertificateManager.swift in Sources */, DAF4579E23D904360018B495 /* UIColorExtension.swift in Sources */, 9350F16423814EC200054BA8 /* OpenHABSitemap.swift in Sources */, + DA2CBDAF24D5FD73003CAE8A /* UnknownCaseRepresentable.swift in Sources */, 9350F10223814CD500054BA8 /* OpenHABItem.swift in Sources */, 9350F10523814CFF00054BA8 /* OpenHABLinkedPage.swift in Sources */, 9350F192238151CE00054BA8 /* StringExtension.swift in Sources */, 9350F18C2381519300054BA8 /* ClientCertificateManager.swift in Sources */, + DADC1EAE24D2CB8C0052B8D4 /* NumberState.swift in Sources */, 9350F1862381516300054BA8 /* KeyedDecodingContainerProtocolExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1762,6 +1791,7 @@ DA07752D2346705F0086C685 /* NotificationController.swift in Sources */, DA0749E023E0BF510057FA83 /* ColorSelection.swift in Sources */, DA65871F236F83CE007E2E7F /* UserDefaultsExtension.swift in Sources */, + DA9721C324E29A8F0092CCFD /* UserDefaultsBacked.swift in Sources */, DA72E1B8236DEA0900B8EF3A /* AppMessageService.swift in Sources */, DA07752B2346705F0086C685 /* ExtensionDelegate.swift in Sources */, DAF4581623DC48400018B495 /* GenericRow.swift in Sources */, @@ -1794,10 +1824,12 @@ DAB9C7B1230B323000A7DB6E /* OpenHABXMLParserTests.swift in Sources */, DA19E25B22FD801D002F8F2F /* OpenHABGeneralTests.swift in Sources */, DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */, + DACC72E224D00D59007EFAE3 /* NumberStateTest.swift in Sources */, 938BF89624EFBC5400E6B52F /* LocalizationTests.swift in Sources */, DA2DC23221F2736C00830730 /* OpenHABJSONParserTests.swift in Sources */, DA966478232EDEAD00CB418B /* MockURLProtocol.swift in Sources */, DAED514F2305CDE3003BCB31 /* XMLData.swift in Sources */, + DA2CBDB124D7562C003CAE8A /* ParseAsTest.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1967,7 +1999,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1979,7 +2011,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2011,7 +2043,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2023,7 +2055,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2052,7 +2084,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2071,7 +2103,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2100,7 +2132,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2118,7 +2150,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2148,7 +2180,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2166,7 +2198,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2198,7 +2230,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2215,7 +2247,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2246,14 +2278,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2285,14 +2317,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2321,7 +2353,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2333,7 +2365,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2363,7 +2395,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2375,7 +2407,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2405,7 +2437,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2417,7 +2449,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2450,7 +2482,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2462,7 +2494,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2603,7 +2635,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2620,7 +2652,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2650,7 +2682,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410445; + CURRENT_PROJECT_VERSION = 1580410451; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2667,7 +2699,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.3.25; + MARKETING_VERSION = 2.4.2; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme index 5552383e5..4f00a4461 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHAB.xcscheme @@ -1,6 +1,6 @@ - - - - diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme index 2a63e88c5..5825c9ceb 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme @@ -1,6 +1,6 @@ - - - - diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme index d9e5f7cbc..b8cca27d4 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme @@ -1,6 +1,6 @@ - + notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> + - + - + notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme index 868f13fce..449e47642 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme @@ -1,6 +1,6 @@ - + - + - + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme index 94cf30e66..3bd32af54 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme @@ -1,6 +1,6 @@ - + - + - + - - - - - + diff --git a/openHAB/AppDelegate.swift b/openHAB/AppDelegate.swift index eb8247436..800a12113 100644 --- a/openHAB/AppDelegate.swift +++ b/openHAB/AppDelegate.swift @@ -10,7 +10,7 @@ // SPDX-License-Identifier: EPL-2.0 import AVFoundation -import Firebase +import FirebaseCore import Kingfisher import OpenHABCore import os.log diff --git a/openHAB/GenericUITableViewCell.swift b/openHAB/GenericUITableViewCell.swift index 03414b902..e00492315 100644 --- a/openHAB/GenericUITableViewCell.swift +++ b/openHAB/GenericUITableViewCell.swift @@ -36,8 +36,8 @@ class GenericUITableViewCell: UITableViewCell { // self.userInteractionEnabled = NO; } - customTextLabel?.textColor = _widget.labelcolor != "" ? UIColor(fromString: _widget.labelcolor) : .ohLabel - customDetailTextLabel?.textColor = _widget.valuecolor != "" ? UIColor(fromString: _widget.valuecolor) : .ohSecondaryLabel + customTextLabel?.textColor = !(_widget.labelcolor.isEmpty) ? UIColor(fromString: _widget.labelcolor) : .ohLabel + customDetailTextLabel?.textColor = !(_widget.valuecolor.isEmpty) ? UIColor(fromString: _widget.valuecolor) : .ohSecondaryLabel } } diff --git a/openHAB/NewImageUITableViewCell.swift b/openHAB/NewImageUITableViewCell.swift index dc30f9724..c6926c740 100644 --- a/openHAB/NewImageUITableViewCell.swift +++ b/openHAB/NewImageUITableViewCell.swift @@ -40,9 +40,9 @@ class NewImageUITableViewCell: GenericUITableViewCell { guard let widget = widget else { return .empty } switch widget.type { - case "Chart": + case .chart: return .link(url: Endpoint.chart(rootUrl: appData!.openHABRootUrl, period: widget.period, type: widget.item?.type, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: chartStyle).url) - case "Image": + case .image: if let item = widget.item { return widgetPayload(fromItem: item) } @@ -79,7 +79,7 @@ class NewImageUITableViewCell: GenericUITableViewCell { super.traitCollectionDidChange(previousTraitCollection) chartStyle = OHInterfaceStyle.current == .light ? ChartStyle.light : ChartStyle.dark - if widget.type == "Chart" { + if widget.type == .chart { loadImage() } } @@ -127,14 +127,14 @@ class NewImageUITableViewCell: GenericUITableViewCell { private func widgetPayload(fromItem item: OpenHABItem) -> ImageType { switch item.type { - case "Image": + case .image: os_log("Image base64Encoded.", log: .urlComposition, type: .debug) - guard let data = item.state.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters) else { + guard let data = item.state?.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters) else { return .empty } return .embedded(image: UIImage(data: decodedData)) - case "String": - return .link(url: URL(string: item.state)) + case .stringItem: + return .link(url: URL(string: item.state ?? "")) default: return .empty } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index ba48dc6a3..d23e59ee6 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -162,7 +162,7 @@ class OpenHABDrawerTableViewController: UITableViewController { let imageView = UIImageView(frame: cell.customImageView.bounds) cell.customTextLabel?.text = sitemaps[indexPath.row].label - if sitemaps[indexPath.row].icon != "" { + if !sitemaps[indexPath.row].icon.isEmpty { 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: "openHABIcon")) diff --git a/openHAB/OpenHABNotificationsViewController.swift b/openHAB/OpenHABNotificationsViewController.swift index 9d37fce49..7faeb940a 100644 --- a/openHAB/OpenHABNotificationsViewController.swift +++ b/openHAB/OpenHABNotificationsViewController.swift @@ -114,7 +114,7 @@ class OpenHABNotificationsViewController: UITableViewController, SideMenuNavigat if let iconUrl = Endpoint.icon(rootUrl: appData!.openHABRootUrl, version: appData!.openHABVersion, icon: notification.icon, - value: "", + state: "", iconType: .png).url { cell?.imageView?.kf.setImage(with: iconUrl, placeholder: UIImage(named: "openHABIcon")) diff --git a/openHAB/OpenHABTracker.swift b/openHAB/OpenHABTracker.swift index ee3c20f1f..3526df1fb 100644 --- a/openHAB/OpenHABTracker.swift +++ b/openHAB/OpenHABTracker.swift @@ -121,7 +121,7 @@ class OpenHABTracker: NSObject { func trackedRemoteUrl() { let openHABUrl = normalizeUrl(openHABRemoteUrl) - if (openHABUrl?.count ?? 0) > 0 { + if !(openHABUrl ?? "").isEmpty { // delegate?.openHABTrackingProgress("Connecting to remote URL") trackedUrl(URL(string: openHABUrl!)) } else { diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index c0782ac07..b08ea27ed 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -87,6 +87,7 @@ class OpenHABViewController: UIViewController { var iconType: IconType = .png let search = UISearchController(searchResultsController: nil) var filteredPage: OpenHABSitemapPage? + var serverProperties: OpenHABServerProperties? var relevantPage: OpenHABSitemapPage? { if isFiltering { @@ -265,7 +266,7 @@ class OpenHABViewController: UIViewController { if idleOff { UIApplication.shared.isIdleTimerDisabled = true } - if isViewLoaded, view.window != nil, pageUrl != "" { + if isViewLoaded, view.window != nil, !pageUrl.isEmpty { if !pageNetworkStatusChanged() { os_log("OpenHABViewController isViewLoaded, restarting network activity", log: .viewCycle, type: .info) loadPage(false) @@ -348,7 +349,7 @@ class OpenHABViewController: UIViewController { func doRegisterAps() { let prefsURL = Preferences.remoteUrl if prefsURL.contains("openhab.org") { - if deviceId != "", deviceToken != "", deviceName != "" { + if !deviceId.isEmpty, !deviceToken.isEmpty, !deviceName.isEmpty { 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 { @@ -418,107 +419,108 @@ class OpenHABViewController: UIViewController { currentPageOperation = NetworkConnection.page(pageUrl: pageUrl, longPolling: longPolling, openHABVersion: appData?.openHABVersion ?? 2) { [weak self] response in - guard let self = self else { return } + guard let self = self else { return } - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - let headers = response.response?.allHeaderFields - - NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" - if !NetworkConnection.atmosphereTrackingId.isEmpty { - os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) - } - var openHABSitemapPage: OpenHABSitemapPage? - if let data = response.result.value { - // If we are talking to openHAB 1.X, talk XML - if self.appData?.openHABVersion == 1 { - let str = String(decoding: data, as: UTF8.self) - os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + let headers = response.response?.allHeaderFields - guard let doc = try? XMLDocument(data: data) else { return } - if let rootElement = doc.root, let name = rootElement.tag { - os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) - if name == "page" { - openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" + if !NetworkConnection.atmosphereTrackingId.isEmpty { + os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) + } + var openHABSitemapPage: OpenHABSitemapPage? + if let data = response.result.value { + // If we are talking to openHAB 1.X, talk XML + if self.appData?.openHABVersion == 1 { + let str = String(decoding: data, as: UTF8.self) + os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + + guard let doc = try? XMLDocument(data: data) else { return } + if let rootElement = doc.root, let name = rootElement.tag { + os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) + if name == "page" { + openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + } + } + } else { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } - } - } else { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } } - } - self.currentPage = openHABSitemapPage - if self.isFiltering { - self.filterContentForSearchText(self.search.searchBar.text) - } - - self.currentPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - self.widgetTableView.reloadData() - UIApplication.shared.isNetworkActivityIndicatorVisible = false - self.refreshControl?.endRefreshing() - self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] - self.loadPage(true) - 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) + self.currentPage = openHABSitemapPage + if self.isFiltering { + self.filterContentForSearchText(self.search.searchBar.text) + } - NetworkConnection.atmosphereTrackingId = "" - 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 { - os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) - } else { - // Error - DispatchQueue.main.async { - if (error as NSError?)?.code == -1012 { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view - } - } else { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view + self.currentPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } + self.widgetTableView.reloadData() + UIApplication.shared.isNetworkActivityIndicatorVisible = false + self.refreshControl?.endRefreshing() + self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] + self.loadPage(true) + 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 { + os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) + self.loadPage(false) + } else if (error as NSError?)?.code == -999 { + os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) + } else { + // Error + DispatchQueue.main.async { + if (error as NSError?)?.code == -1012 { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } + } else { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } } } } } - } } + currentPageOperation?.resume() os_log("OpenHABViewController request sent", log: .remoteAccess, type: .error) @@ -533,7 +535,7 @@ class OpenHABViewController: UIViewController { self.sitemaps = deriveSitemaps(response.result.value, version: self.appData?.openHABVersion) switch self.sitemaps.count { case 2...: - if self.defaultSitemap != "" { + if !self.defaultSitemap.isEmpty { if let sitemapToOpen = self.sitemap(byName: self.defaultSitemap) { if self.currentPage?.pageId != sitemapToOpen.name { self.currentPage?.widgets.removeAll() // NOTE: remove all widgets to ensure cells get invalidated @@ -641,7 +643,7 @@ class OpenHABViewController: UIViewController { func pageNetworkStatusChanged() -> Bool { os_log("OpenHABViewController pageNetworkStatusChange", log: .remoteAccess, type: .info) - if pageUrl != "" { + if !pageUrl.isEmpty { let pageReachability = NetworkReachabilityManager(host: pageUrl) if !pageNetworkStatusAvailable { pageNetworkStatus = pageReachability?.networkReachabilityStatus @@ -663,7 +665,7 @@ class OpenHABViewController: UIViewController { guard let searchText = searchText else { return } filteredPage = currentPage?.filter { - $0.label.lowercased().contains(searchText.lowercased()) && $0.type != "Frame" + $0.label.lowercased().contains(searchText.lowercased()) && $0.type != .frame } filteredPage?.sendCommand = { [weak self] item, command in self?.sendCommand(item, commandToSend: command) @@ -717,21 +719,34 @@ extension OpenHABViewController: OpenHABTrackerDelegate { NetworkConnection.tracker(openHABRootUrl: openHABRootUrl) { response in switch response.result { case .success: - os_log("This is an openHAB 2.X", log: .remoteAccess, type: .info) - self.appData?.openHABVersion = 2 + DispatchQueue.main.async { UIApplication.shared.isNetworkActivityIndicatorVisible = false } - self.selectSitemap() + + if let data = response.result.value { + do { + self.serverProperties = try data.decoded(as: OpenHABServerProperties.self) + os_log("This is an openHAB >= 2.X", log: .remoteAccess, type: .info) + self.appData?.openHABVersion = 2 + self.selectSitemap() + } catch { + os_log("Could not decode response as JSON, test for OH1", log: .notifications, type: .error, error.localizedDescription) + let str = String(decoding: data, as: UTF8.self) + if str.hasPrefix(" CGFloat { let widget: OpenHABWidget? = relevantPage?.widgets[indexPath.row] switch widget?.type { - case "Frame": + case .frame: return widget?.label.count ?? 0 > 0 ? 35.0 : 0 - case "Image", "Chart", "Video": + case .image, .chart, .video: return UITableView.automaticDimension - case "Webview", "Mapview": - if let height = widget?.height, Int(height) != 0 { + case .webview, .mapview: + if let height = widget?.height { // calculate webview/mapview height and return it - let heightValue = (Double(height) ?? 0.0) * 44 + let heightValue = height * 44 os_log("Webview/Mapview height would be %g", log: .viewCycle, type: .info, heightValue) return CGFloat(heightValue) } else { @@ -992,45 +1007,46 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { let cell: UITableViewCell switch widget?.type { - case "Frame": + case .frame: cell = tableView.dequeueReusableCell(for: indexPath) as FrameUITableViewCell - case "Switch": + case .switchWidget: // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 - if widget?.mappings.count ?? 0 > 0 { + if !(widget?.mappings ?? []).isEmpty { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell - // RollershutterItem changed to Rollershutter in later builds of OH2 - } else if let type = widget?.item?.type, type == "Switch" { + } else if widget?.item?.isOfTypeOrGroupType(.switchItem) ?? false { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell - } else if let type = widget?.item?.type, type.isAny(of: "RollershutterItem", "Rollershutter") || (type == "Group" && widget?.item?.groupType == "Rollershutter") { + } else if widget?.item?.isOfTypeOrGroupType(.rollershutter) ?? false { cell = tableView.dequeueReusableCell(for: indexPath) as RollershutterUITableViewCell - } else if widget?.item?.stateDescription?.options.count ?? 0 > 0 { + } else if !(widget?.mappingsOrItemOptions ?? []).isEmpty { cell = tableView.dequeueReusableCell(for: indexPath) as SegmentedUITableViewCell } else { cell = tableView.dequeueReusableCell(for: indexPath) as SwitchUITableViewCell } - case "Setpoint": + case .setpoint: cell = tableView.dequeueReusableCell(for: indexPath) as SetpointUITableViewCell - case "Slider": + case .slider: cell = tableView.dequeueReusableCell(for: indexPath) as SliderUITableViewCell - case "Selection": + case .selection: cell = tableView.dequeueReusableCell(for: indexPath) as SelectionUITableViewCell - case "Colorpicker": + case .colorpicker: cell = tableView.dequeueReusableCell(for: indexPath) as ColorPickerUITableViewCell (cell as? ColorPickerUITableViewCell)?.delegate = self - case "Image", "Chart": + case .image, .chart: cell = tableView.dequeueReusableCell(withIdentifier: openHABViewControllerImageViewCellReuseIdentifier, for: indexPath) as! NewImageUITableViewCell (cell as? NewImageUITableViewCell)?.didLoad = { [weak self] in self?.updateWidgetTableView() } - case "Video": + case .video: cell = tableView.dequeueReusableCell(withIdentifier: "VideoUITableViewCell", for: indexPath) as! VideoUITableViewCell (cell as? VideoUITableViewCell)?.didLoad = { [weak self] in self?.updateWidgetTableView() } - case "Webview": + case .webview: cell = tableView.dequeueReusableCell(for: indexPath) as WebUITableViewCell - case "Mapview": + case .mapview: cell = (tableView.dequeueReusableCell(withIdentifier: openHABViewControllerMapViewCellReuseIdentifier) as? MapViewTableViewCell)! + case .group, .text: + cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell default: cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell } @@ -1040,7 +1056,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { if let urlc = Endpoint.icon(rootUrl: openHABRootUrl, version: appData?.openHABVersion ?? 2, icon: widget?.icon, - value: widget?.item?.state ?? "", + state: widget?.iconState() ?? "", iconType: iconType).url { var imageRequest = URLRequest(url: urlc) imageRequest.timeoutInterval = 10.0 @@ -1083,9 +1099,9 @@ 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") { + if let type = nextWidget?.type, type.isAny(of: .frame, .image, .video, .webview, .chart) { cell.separatorInset = UIEdgeInsets.zero - } else if !(widget?.type == "Frame") { + } else if !(widget?.type == .frame) { cell.separatorInset = UIEdgeInsets(top: 0, left: 60, bottom: 0, right: 0) } } @@ -1115,7 +1131,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { newViewController.pageUrl = widget?.linkedPage?.link ?? "" newViewController.openHABRootUrl = openHABRootUrl navigationController?.pushViewController(newViewController, animated: true) - } else if widget?.type == "Selection" { + } else if widget?.type == .selection { os_log("Selected selection widget", log: .viewCycle, type: .info) selectedWidgetRow = indexPath.row @@ -1143,7 +1159,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { @available(iOS 13.0, *) func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { - if let cell = tableView.cellForRow(at: indexPath) as? GenericUITableViewCell, cell.widget.type == "Text", let text = cell.widget?.labelValue ?? cell.widget?.labelText, !text.isEmpty { + if let cell = tableView.cellForRow(at: indexPath) as? GenericUITableViewCell, cell.widget.type == .text, let text = cell.widget?.labelValue ?? cell.widget?.labelText, !text.isEmpty { return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in let copy = UIAction(title: NSLocalizedString("copy_label", comment: ""), image: UIImage(systemName: "square.and.arrow.up")) { _ in UIPasteboard.general.string = text diff --git a/openHAB/ScaleAspectFitImageView.swift b/openHAB/ScaleAspectFitImageView.swift index 06aa7e714..091727d6f 100644 --- a/openHAB/ScaleAspectFitImageView.swift +++ b/openHAB/ScaleAspectFitImageView.swift @@ -15,26 +15,26 @@ public class ScaleAspectFitImageView: UIImageView { private var aspectRatioConstraint: NSLayoutConstraint? override public var image: UIImage? { didSet { - self.updateAspectRatioConstraint() + updateAspectRatioConstraint() } } - required public init?(coder aDecoder: NSCoder) { + public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - public override init(frame: CGRect) { + override public init(frame: CGRect) { super.init(frame: frame) setup() } - public override init(image: UIImage!) { + override public init(image: UIImage!) { super.init(image: image) setup() } - public override init(image: UIImage!, highlightedImage: UIImage?) { + override public init(image: UIImage!, highlightedImage: UIImage?) { super.init(image: image, highlightedImage: highlightedImage) setup() } diff --git a/openHAB/SetpointUITableViewCell.swift b/openHAB/SetpointUITableViewCell.swift index 9e04c2753..60cbd0fc9 100644 --- a/openHAB/SetpointUITableViewCell.swift +++ b/openHAB/SetpointUITableViewCell.swift @@ -15,10 +15,6 @@ import os.log import UIKit class SetpointUITableViewCell: GenericUITableViewCell { - private var isIntStep: Bool { - widget.step.truncatingRemainder(dividingBy: 1) == 0 - } - @IBOutlet private var downButton: DynamicButton! @IBOutlet private var upButton: DynamicButton! @@ -42,45 +38,29 @@ class SetpointUITableViewCell: GenericUITableViewCell { super.displayWidget() } + private func handleUpDown(down: Bool) { + var numberState = widget?.stateValueAsNumberState + let stateValue = numberState?.value ?? widget.minValue + let newValue: Double + switch down { + case true: + newValue = stateValue - widget.step + case false: + newValue = stateValue + widget.step + } + if newValue >= widget.minValue, newValue <= widget.maxValue { + numberState?.value = newValue + widget.sendItemUpdate(state: numberState) + } + } + @objc func decreaseValue(_ sender: Any?) { - os_log("down button pressed", log: .viewCycle, type: .info) - - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() - widget.step - newValue = max(newValue, widget.minValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() - Int(widget.step) - newValue = max(newValue, Int(widget.minValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + handleUpDown(down: true) } @objc func increaseValue(_ sender: Any?) { - os_log("up button pressed", log: .viewCycle, type: .info) - - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() + widget.step - newValue = min(newValue, widget.maxValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() + Int(widget.step) - newValue = min(newValue, Int(widget.maxValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + handleUpDown(down: false) } } diff --git a/openHAB/SliderUITableViewCell.swift b/openHAB/SliderUITableViewCell.swift index 460dbb41c..b99bb9da7 100644 --- a/openHAB/SliderUITableViewCell.swift +++ b/openHAB/SliderUITableViewCell.swift @@ -15,6 +15,7 @@ import UIKit class SliderUITableViewCell: GenericUITableViewCell { private var isInTransition: Bool = false + private var step: Float = 1.0 private var transitionItem: DispatchWorkItem? private var throttler: Throttler? private var throttlingInterval: TimeInterval? = 0 { @@ -48,6 +49,11 @@ class SliderUITableViewCell: GenericUITableViewCell { selectionStyle = .none separatorInset = .zero throttlingInterval = 0.1 + if let widget = widget { + step = Float(widget.step) + } else { + step = 1.0 + } } @IBAction private func sliderValueChanged(_ sender: Any) { @@ -80,7 +86,7 @@ class SliderUITableViewCell: GenericUITableViewCell { } private func adj(_ raw: Double) -> Double { - var valueAdjustedToStep = floor((raw - widget.minValue) / widget.step) * widget.step + var valueAdjustedToStep = Double(floor(Float(((raw - widget.minValue))) / step) * step) valueAdjustedToStep += widget.minValue return min(max(valueAdjustedToStep, widget.minValue), widget.maxValue) } @@ -96,21 +102,39 @@ class SliderUITableViewCell: GenericUITableViewCell { override func displayWidget() { guard !isInTransition else { return } - customTextLabel?.text = widget.labelText - widgetSlider?.minimumValue = Float(widget.minValue) - widgetSlider?.maximumValue = Float(widget.maxValue) - let widgetValue = adjustedValue() - widgetSlider?.value = Float(widgetValue) - // if there is a formatted value in widget label, take it. Otherwise display local value - if let labelValue = widget?.labelValue { - customDetailText?.text = labelValue + if let item = widget.item, item.isOfTypeOrGroupType(.color) { + widgetSlider?.minimumValue = 0.0 + widgetSlider?.maximumValue = 100.0 + step = 1.0 + widgetSlider.value = Float(item.state?.parseAsBrightness() ?? 0) } else { - customDetailText?.text = widgetValue.valueText(step: widget.step) + // Fix "The stepSize must be 0, or a factor of the valueFrom-valueTo range" exception + widgetSlider?.minimumValue = Float(widget.minValue) + widgetSlider?.maximumValue = Float(widget.maxValue) + let widgetValue = adjustedValue() + widgetSlider?.value = Float(widgetValue) + step = Float(widget.step) + + // if there is a formatted value in widget label, take it. Otherwise display local value + if let labelValue = widget?.labelValue { + customDetailText?.text = labelValue + } else { + customDetailText?.text = widgetValue.valueText(step: Double(step)) + } } + customTextLabel?.text = widget.labelText } private func sliderDidChange(toValue value: Double) { os_log("Slider new value = %g", log: .default, type: .info, value) - widget.sendCommand(value.valueText(step: widget.step)) + + if let item = widget.item, item.isOfTypeOrGroupType(.color) { + widget.sendCommand(value.valueText(step: Double(step))) + // connection.httpClient.sendItemCommand(item, value) + } else { + widget.sendCommand(value.valueText(step: Double(step))) + + // connection.httpClient.sendItemUpdate(item, item.state?.asNumber.withValue(value.toFloat())) + } } } diff --git a/openHAB/SwitchUITableViewCell.swift b/openHAB/SwitchUITableViewCell.swift index 24a640581..45a98dc38 100644 --- a/openHAB/SwitchUITableViewCell.swift +++ b/openHAB/SwitchUITableViewCell.swift @@ -9,6 +9,7 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import os.log import UIKit @@ -38,7 +39,7 @@ class SwitchUITableViewCell: GenericUITableViewCell { state = (widget.item?.state) ?? "" } customDetailTextLabel?.text = widget.labelValue ?? "" - widgetSwitch?.isOn = (state == "ON" ? true : false) + widgetSwitch?.isOn = state.parseAsBool() widgetSwitch?.addTarget(self, action: .switchChange, for: .valueChanged) super.displayWidget() } diff --git a/openHAB/openHAB-Info.plist b/openHAB/openHAB-Info.plist index 07039ec38..e38b45929 100644 --- a/openHAB/openHAB-Info.plist +++ b/openHAB/openHAB-Info.plist @@ -2,8 +2,6 @@ - firebase_crashlytics_collection_enabled - CFBundleDevelopmentRegion en CFBundleDisplayName @@ -112,5 +110,7 @@ + firebase_crashlytics_collection_enabled + diff --git a/openHABCore/Sources/Model/NumberState.swift b/openHABCore/Sources/Model/NumberState.swift new file mode 100644 index 000000000..08111a0c1 --- /dev/null +++ b/openHABCore/Sources/Model/NumberState.swift @@ -0,0 +1,50 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +public struct NumberState: CustomStringConvertible, Equatable { + public var description: String { + toString(locale: Locale.current) + } + + public var value: Double + private(set) var unit: String? = "" + private(set) var format: String? = "" + + public func toString(locale: Locale?) -> String { + if let format = format, format.isEmpty == false { + let actualFormat = format.replacingOccurrences(of: "%unit%", with: unit ?? "") + if format.contains("%d") == true { + return String(format: actualFormat, locale: locale, Int(value)) + } else { + return String(format: actualFormat, locale: locale, value) + } + } + if let unit = unit, unit.isEmpty == false { + return "\(formatValue()) \(unit)" + } else { + return formatValue() + } + } + + public func formatValue() -> String { + String(value) + } + + private func getActualValue() -> NSNumber { + if format?.contains("%d") == true { + return NSNumber(value: Int(value)) + } else { + return NSNumber(value: value) + } + } +} diff --git a/openHABCore/Sources/Model/OpenHABItem.swift b/openHABCore/Sources/Model/OpenHABItem.swift index 9640acdb0..0358f5839 100644 --- a/openHABCore/Sources/Model/OpenHABItem.swift +++ b/openHABCore/Sources/Model/OpenHABItem.swift @@ -13,24 +13,60 @@ import CoreLocation import Fuzi import os.log import UIKit - public final class OpenHABItem: NSObject, CommItem { - public var type = "" - public var groupType = "" + public enum ItemType: String { + case color = "Color" + case contact = "Contact" + case dateTime = "DateTime" + case dimmer = "Dimmer" + case group = "Group" + case image = "Image" + case location = "Location" + case number = "Number" + case numberWithDimension = "NumberWithDimension" + case player = "Player" + case rollershutter = "Rollershutter" + case stringItem = "String" + case switchItem = "Switch" + } + + public var type: ItemType? + public var groupType: ItemType? public var name = "" - public var state = "" + public var state: String? public var link = "" public var label = "" public var stateDescription: OpenHABStateDescription? + public var readOnly = false + public var members: [OpenHABItem] = [] + public var category = "" + public var options: [OpenHABOptions] = [] + + var canBeToggled: Bool { + isOfTypeOrGroupType(ItemType.color) || + isOfTypeOrGroupType(ItemType.contact) || + isOfTypeOrGroupType(ItemType.dimmer) || + isOfTypeOrGroupType(ItemType.rollershutter) || + isOfTypeOrGroupType(ItemType.switchItem) || + isOfTypeOrGroupType(ItemType.player) + } - public init(name: String, type: String, state: String, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?) { + public init(name: String, type: String, state: String?, link: String, label: String?, groupType: String?, stateDescription: OpenHABStateDescription?, members: [OpenHABItem], category: String?, options: [OpenHABOptions]?) { self.name = name - self.type = type - self.state = state + self.type = type.toItemType() + if let state = state, (state == "NULL" || state == "UNDEF" || state.caseInsensitiveCompare("undefined") == .orderedSame) { + self.state = nil + } else { + self.state = state + } self.link = link self.label = label ?? "" - self.groupType = groupType ?? "" + self.groupType = groupType?.toItemType() self.stateDescription = stateDescription + readOnly = stateDescription?.readOnly ?? false + self.members = members + self.category = category ?? "" + self.options = options ?? [] } public init(xml xmlElement: XMLElement) { @@ -38,8 +74,8 @@ public final class OpenHABItem: NSObject, CommItem { for child in xmlElement.children { switch child.tag { case "name": name = child.stringValue - case "type": type = child.stringValue - case "groupType": groupType = child.stringValue + case "type": type = child.stringValue.toItemType() + case "groupType": groupType = child.stringValue.toItemType() case "state": state = child.stringValue case "link": link = child.stringValue default: @@ -47,21 +83,25 @@ public final class OpenHABItem: NSObject, CommItem { } } } + + public func isOfTypeOrGroupType(_ type: ItemType) -> Bool { + self.type == type || groupType == type + } } +extension OpenHABItem.ItemType: Decodable {} + extension OpenHABItem { public func stateAsDouble() -> Double { - state.numberValue?.doubleValue ?? 0 + state?.numberValue?.doubleValue ?? 0 } public func stateAsInt() -> Int { - state.numberValue?.intValue ?? 0 + state?.numberValue?.intValue ?? 0 } public func stateAsUIColor() -> UIColor { - if state == "Uninitialized" { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) - } else { + if let state = state { let values = state.components(separatedBy: ",") if values.count == 3 { let hue = CGFloat(state: values[0], divisor: 360) @@ -70,20 +110,26 @@ extension OpenHABItem { os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) } else { - return UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + return .black } + } else { + return .black } } public func stateAsLocation() -> CLLocation? { - if type == "Location" { - // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') - let locationComponents = state.components(separatedBy: ",") - if locationComponents.count >= 2 { - let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) - let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) - - return CLLocation(latitude: latitude, longitude: longitude) + if type == .location { + // Example of `state` string for location: '0.000000,0.000000,0.0' (',,') + if let state = state { + let locationComponents = state.components(separatedBy: ",") + if locationComponents.count >= 2 { + let latitude = CLLocationDegrees(Double(locationComponents[0]) ?? 0.0) + let longitude = CLLocationDegrees(Double(locationComponents[1]) ?? 0.0) + + return CLLocation(latitude: latitude, longitude: longitude) + } + } else { + return nil } } return nil @@ -96,22 +142,27 @@ extension OpenHABItem { let groupType: String? let name: String let link: String - let state: String + let state: String? let label: String? let stateDescription: OpenHABStateDescription.CodingData? + let members: [OpenHABItem.CodingData]? + let category: String? + let options: [OpenHABOptions]? } } extension OpenHABItem.CodingData { public var openHABItem: OpenHABItem { - OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription) + let mappedMembers = members?.map(\.openHABItem) ?? [] + + return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, members: mappedMembers, category: category, options: options) } } extension CGFloat { init(state string: String, divisor: Float) { let numberFormatter = NumberFormatter() - numberFormatter.locale = Locale(identifier: "EN") + numberFormatter.locale = Locale(identifier: "US") if let number = numberFormatter.number(from: string) { self.init(number.floatValue / divisor) } else { diff --git a/openHABCore/Sources/Model/OpenHABServerProperties.swift b/openHABCore/Sources/Model/OpenHABServerProperties.swift new file mode 100644 index 000000000..21693b4b2 --- /dev/null +++ b/openHABCore/Sources/Model/OpenHABServerProperties.swift @@ -0,0 +1,34 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +public class OpenHABServerProperties: Decodable { + class OpenHABLink: Decodable { + public var type = "" + public var url = "" + } + + let version: String + let links: [OpenHABLink] + + public var habPanelUrl: String? { + linkUrl(byType: "habpanel") + } + + public func linkUrl(byType type: String?) -> String? { + if let index = links.firstIndex(where: { $0.type == type }) { + return links[index].url + } else { + return nil + } + } +} diff --git a/openHABCore/Sources/Model/OpenHABSitemapPage.swift b/openHABCore/Sources/Model/OpenHABSitemapPage.swift index 1f136a59a..1c967fe3e 100644 --- a/openHABCore/Sources/Model/OpenHABSitemapPage.swift +++ b/openHABCore/Sources/Model/OpenHABSitemapPage.swift @@ -112,7 +112,7 @@ extension OpenHABSitemapPage { extension OpenHABSitemapPage.CodingData { public var openHABSitemapPage: OpenHABSitemapPage { - let mappedWidgets = widgets?.map { $0.openHABWidget } ?? [] + let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] return OpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) } } diff --git a/openHABCore/Sources/Model/OpenHABStateDescription.swift b/openHABCore/Sources/Model/OpenHABStateDescription.swift index 950918b39..ee126ac50 100644 --- a/openHABCore/Sources/Model/OpenHABStateDescription.swift +++ b/openHABCore/Sources/Model/OpenHABStateDescription.swift @@ -19,12 +19,31 @@ public class OpenHABStateDescription { public var options: [OpenHABOptions] = [] - init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?) { + public var numberPattern: String? + + init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?, pattern: String?) { self.minimum = minimum ?? 0.0 self.maximum = maximum ?? 100.0 self.step = step ?? 1.0 self.readOnly = readOnly ?? false self.options = options ?? [] + + // Remove transformation instructions (e.g. for 'MAP(foo.map):%s' keep only '%s') + + let regexPattern = #"^[A-Z]+(\(.*\))?:(.*)$"# + let regex = try? NSRegularExpression(pattern: regexPattern, options: .caseInsensitive) + if let pattern = pattern { + let nsrange = NSRange(pattern.startIndex ..< pattern.endIndex, in: pattern) + if let match = regex?.firstMatch(in: pattern, options: [], range: nsrange) { + if let range = Range(match.range(at: 2), in: pattern) { + numberPattern = String(pattern[range]) + } + } else { + numberPattern = pattern + } + } else { + numberPattern = nil + } } } @@ -35,11 +54,12 @@ extension OpenHABStateDescription { let step: Double? let readOnly: Bool? let options: [OpenHABOptions]? + let pattern: String? } } extension OpenHABStateDescription.CodingData { var openHABStateDescription: OpenHABStateDescription { - OpenHABStateDescription(minimum: minimum, maximum: maximum, step: step, readOnly: readOnly, options: options) + OpenHABStateDescription(minimum: minimum, maximum: maximum, step: step, readOnly: readOnly, options: options, pattern: pattern) } } diff --git a/openHABCore/Sources/Model/OpenHABWidget.swift b/openHABCore/Sources/Model/OpenHABWidget.swift index e2ee3fb55..8f988954c 100644 --- a/openHABCore/Sources/Model/OpenHABWidget.swift +++ b/openHABCore/Sources/Model/OpenHABWidget.swift @@ -50,20 +50,38 @@ protocol Widget: AnyObject { } public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { + public enum WidgetType: String { + case chart = "Chart" + case colorpicker = "Colorpicker" + case defaultWidget = "Default" + case frame = "Frame" + case group = "Group" + case image = "Image" + case mapview = "Mapview" + case selection = "Selection" + case setpoint = "Setpoint" + case slider = "Slider" + case switchWidget = "Switch" + case text = "Text" + case video = "Video" + case webview = "Webview" + case unknown = "Unknown" + } + public var id: String = "" public var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? public var widgetId = "" public var label = "" public var icon = "" - public var type = "" + public var type: WidgetType? public var url = "" public var period = "" public var minValue = 0.0 public var maxValue = 100.0 public var step = 1.0 public var refresh = 0 - public var height = "" + public var height: Double? public var isLeaf = false public var iconColor = "" public var labelcolor = "" @@ -78,6 +96,8 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var mappings: [OpenHABWidgetMapping] = [] public var image: UIImage? public var widgets: [OpenHABWidget] = [] + public var visibility = true + public var switchSupport = false // Text prior to "[" public var labelText: String? { @@ -106,6 +126,36 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { } } + public var stateValueAsBool: Bool? { + item?.state?.parseAsBool() + } + + public var stateValueAsBrightness: Int? { + item?.state?.parseAsBrightness() + } + + public var stateValueAsUIColor: UIColor? { + item?.state?.parseAsUIColor() + } + + public var stateValueAsNumberState: NumberState? { + item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) + } + + public func sendItemUpdate(state: NumberState?) { + guard let item = item, let state = state else { + os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) + return + } + if item.isOfTypeOrGroupType(.numberWithDimension) { + // For number items, include unit (if present) in command + sendCommand(state.toString(locale: Locale(identifier: "US"))) + } else { + // For all other items, send the plain value + sendCommand(state.formatValue()) + } + } + public func sendCommandDouble(_ command: Double) { sendCommand(String(command)) } @@ -125,15 +175,44 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public func mappingIndex(byCommand command: String?) -> Int? { mappingsOrItemOptions.firstIndex { $0.command == command } } + + public func iconState() -> String { + var iconState = item?.state ?? "" + if let item = item, let itemState = item.state { + if item.isOfTypeOrGroupType(.color) { + // For items that control a color item fetch the correct icon + if type == .slider || (type == .switchWidget && mappings.isEmpty) { + if let brightness = itemState.parseAsBrightness() { + iconState = String(brightness) + if type == .switchWidget { + iconState = iconState == "0" ? "OFF" : "ON" + } + } else { + iconState = "OFF" + } + } else if let color = itemState.parseAsUIColor() { + iconState = "#\(color.toHex() ?? "000000")" + } + } else if type == .switchWidget, mappings.isEmpty, !item.isOfTypeOrGroupType(.rollershutter) { + // For switch items without mappings (just ON and OFF) that control a dimmer item + // and which are not ON or OFF already, set the state to "OFF" instead of 0 + // or to "ON" to fetch the correct icon + iconState = (itemState == "0" || itemState == "OFF") ? "OFF" : "ON" + } + } + return iconState + } +} + +extension OpenHABWidget.WidgetType: Decodable {} + +extension OpenHABWidget.WidgetType: UnknownCaseRepresentable { + static var unknownCase: OpenHABWidget.WidgetType = .unknown } 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 { - guard let double = with else { return "" } - return String(format: "%.1f", double) - } + convenience init(widgetId: String, label: String, icon: String, type: WidgetType, 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], visibility: Bool?, switchSupport: Bool?) { self.init() id = widgetId self.widgetId = widgetId @@ -151,7 +230,7 @@ extension OpenHABWidget { } else { self.refresh = 0 } - self.height = toString(height) + self.height = height self.isLeaf = isLeaf ?? false self.iconColor = iconColor ?? "" labelcolor = labelColor ?? "" @@ -169,6 +248,8 @@ extension OpenHABWidget { // Sanitize minValue, maxValue and step: min <= max, step >= 0 self.maxValue = max(self.minValue, self.maxValue) self.step = abs(self.step) + self.visibility = visibility ?? true + self.switchSupport = switchSupport ?? false } convenience init(xml xmlElement: XMLElement) { @@ -179,7 +260,7 @@ extension OpenHABWidget { switch child.tag { case "widgetId": widgetId = child.stringValue case "label": label = child.stringValue - case "type": type = child.stringValue + case "type": type = child.stringValue.toWidgetType() case "icon": icon = child.stringValue case "url": url = child.stringValue case "period": period = child.stringValue @@ -189,7 +270,7 @@ extension OpenHABWidget { case "service": service = child.stringValue case "state": state = child.stringValue case "text": text = child.stringValue - case "height": height = child.stringValue + case "height": height = Double(child.stringValue) case "encoding": encoding = child.stringValue // Double case "minValue": minValue = Double(child.stringValue) ?? 0.0 @@ -216,7 +297,7 @@ extension OpenHABWidget { public struct CodingData: Decodable { let widgetId: String let label: String - let type: String + let type: WidgetType let icon: String let url: String? let period: String? @@ -239,14 +320,16 @@ extension OpenHABWidget { let linkedPage: OpenHABLinkedPage? let mappings: [OpenHABWidgetMapping] let widgets: [OpenHABWidget.CodingData] + let visibility: Bool? + let switchSupport: Bool? } } // swiftlint:disable line_length extension OpenHABWidget.CodingData { var openHABWidget: OpenHABWidget { - 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) + let mappedWidgets = widgets.map(\.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, visibility: visibility, switchSupport: switchSupport) } } diff --git a/openHABCore/Sources/Util/Endpoint.swift b/openHABCore/Sources/Util/Endpoint.swift index b3ed68cb6..b484a9c23 100644 --- a/openHABCore/Sources/Util/Endpoint.swift +++ b/openHABCore/Sources/Util/Endpoint.swift @@ -73,14 +73,14 @@ extension Endpoint { } // swiftlint:disable:next function_parameter_count - public static func chart(rootUrl: String, period: String?, type: String?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> Endpoint { + public static func chart(rootUrl: String, period: String?, type: OpenHABItem.ItemType?, service: String?, name: String?, legend: Bool?, theme: ChartStyle = .light) -> 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") { + if type == .group { endpoint.queryItems.append(URLQueryItem(name: "groups", value: name)) } else { endpoint.queryItems.append(URLQueryItem(name: "items", value: name)) @@ -100,7 +100,7 @@ extension Endpoint { return endpoint } - public static func icon(rootUrl: String, version: Int, icon: String?, value: String, iconType: IconType) -> Endpoint { + public static func icon(rootUrl: String, version: Int, icon: String?, state: String, iconType: IconType) -> Endpoint { guard let icon = icon, !icon.isEmpty else { return Endpoint(baseURL: "", path: "", queryItems: []) } @@ -109,7 +109,7 @@ extension Endpoint { if version == 2 { return Endpoint(baseURL: rootUrl, path: "/icon/\(icon)", - queryItems: [URLQueryItem(name: "state", value: value), + queryItems: [URLQueryItem(name: "state", value: state), URLQueryItem(name: "format", value: (iconType == .png) ? "PNG" : "SVG")]) } else { return Endpoint(baseURL: rootUrl, diff --git a/openHABCore/Sources/Util/Preferences.swift b/openHABCore/Sources/Util/Preferences.swift index 640d5d893..edf59fb64 100644 --- a/openHABCore/Sources/Util/Preferences.swift +++ b/openHABCore/Sources/Util/Preferences.swift @@ -77,27 +77,20 @@ public struct UserDefaultURL { } public struct Preferences { - static private let defaults = UserDefaults.standard + private static let defaults = UserDefaults.standard - @UserDefaultURL("localUrl", defaultValue: "") static public var localUrl: String - @UserDefaultURL("remoteUrl", defaultValue: "https://openhab.org:8444") static public var remoteUrl: String + @UserDefaultURL("localUrl", defaultValue: "") public static var localUrl: String + @UserDefaultURL("remoteUrl", defaultValue: "https://openhab.org:8444") public static var remoteUrl: String - @UserDefault("username", defaultValue: "test") static public var username: String - @UserDefault("password", defaultValue: "test") static public var password: String + @UserDefault("username", defaultValue: "test") public static var username: String + @UserDefault("password", defaultValue: "test") public static var password: String @UserDefault("alwaysSendCreds", defaultValue: false) public static var alwaysSendCreds: Bool - @UserDefault("ignoreSSL", defaultValue: false) static public var ignoreSSL: Bool + @UserDefault("ignoreSSL", defaultValue: false) public static var ignoreSSL: Bool // @UserDefault("sitemapName", defaultValue: "watch") static public var sitemapName: String - @UserDefault("demomode", defaultValue: true) static public var demomode: Bool - @UserDefault("idleOff", defaultValue: false) static public var idleOff: Bool - @UserDefault("realTimeSliders", defaultValue: false) static public var realTimeSliders: Bool - @UserDefault("iconType", defaultValue: 0) static public var iconType: Int - @UserDefault("defaultSitemap", defaultValue: "demo") static public var defaultSitemap: String - @UserDefault("sendCrashReports", defaultValue: false) static public var sendCrashReports: Bool - - static func readActiveUrl() -> String { - if Preferences.remoteUrl != "" { - return Preferences.remoteUrl - } - return Preferences.localUrl - } + @UserDefault("demomode", defaultValue: true) public static var demomode: Bool + @UserDefault("idleOff", defaultValue: false) public static var idleOff: Bool + @UserDefault("realTimeSliders", defaultValue: false) public static var realTimeSliders: Bool + @UserDefault("iconType", defaultValue: 0) public static var iconType: Int + @UserDefault("defaultSitemap", defaultValue: "demo") public static var defaultSitemap: String + @UserDefault("sendCrashReports", defaultValue: false) public static var sendCrashReports: Bool } diff --git a/openHABCore/Sources/Util/StringExtension.swift b/openHABCore/Sources/Util/StringExtension.swift index 9a7a80767..2f2ce6cb3 100644 --- a/openHABCore/Sources/Util/StringExtension.swift +++ b/openHABCore/Sources/Util/StringExtension.swift @@ -10,6 +10,8 @@ // SPDX-License-Identifier: EPL-2.0 import Foundation +import MapKit +import os.log extension String { var doubleValue: Double { @@ -41,4 +43,72 @@ extension String { formatter.decimalSeparator = "." return formatter.number(from: filter("01234567890.-".contains)) } + + var asDouble: Double { + numberValue?.doubleValue ?? 0 + } + + func toItemType() -> OpenHABItem.ItemType? { + var typeString: String = self + // Earlier OH2 versions returned e.g. 'Switch' as 'SwitchItem' + if hasSuffix("Item") { + typeString = String(dropLast(4)) + } + // types can have subtypes (e.g. 'Number:Temperature'); split off those + let firstColon = firstIndex(of: ":") + if let firstColon = firstColon { + typeString = String(typeString[.. OpenHABWidget.WidgetType? { + OpenHABWidget.WidgetType(rawValue: self) + } + + public func parseAsBool() -> Bool { + if self == "ON" { return true } + if let brightness = parseAsBrightness() { return brightness != 0 } + if let decimalValue = Int(self) { + return decimalValue > 0 + } else { + return false + } + } + + public func parseAsNumber(format: String? = nil) -> NumberState { + switch self { + case "ON": return NumberState(value: 100.0) + case "OFF": return NumberState(value: 0.0) + default: + let components = split(separator: " ").map { String($0) } + let number = String(components[safe: 0] ?? "") + let unit = components[safe: 1] + return NumberState(value: number.asDouble, unit: unit, format: format) + } + } + + public func parseAsUIColor() -> UIColor? { + guard self != "Uninitialized" else { + return .black + } + let values = components(separatedBy: ",") + guard values.count == 3 else { return nil } + let hue = CGFloat(state: values[0], divisor: 360) + let saturation = CGFloat(state: values[1], divisor: 100) + let brightness = CGFloat(state: values[2], divisor: 100) + os_log("hue saturation brightness: %g %g %g", log: .default, type: .info, hue, saturation, brightness) + return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) + } + + public func parseAsBrightness() -> Int? { + let values = components(separatedBy: ",") + guard values.count == 3 else { return nil } + return Int(values[2].asDouble.rounded()) + } } diff --git a/openHABCore/Sources/Util/UIColorExtension.swift b/openHABCore/Sources/Util/UIColorExtension.swift index 3e25d71e4..57068c805 100644 --- a/openHABCore/Sources/Util/UIColorExtension.swift +++ b/openHABCore/Sources/Util/UIColorExtension.swift @@ -201,4 +201,29 @@ public extension UIColor { self.init(red: red, green: green, blue: blue, alpha: 1) } + + // Inspired by https://cocoacasts.com/from-hex-to-uicolor-and-back-in-swift + + // MARK: - From UIColor to String + + func toHex(alpha: Bool = false) -> String? { + guard let components = cgColor.components, components.count >= 3 else { + return nil + } + + let red = Float(components[0]) + let green = Float(components[1]) + let blue = Float(components[2]) + var a = Float(1.0) + + if components.count >= 4 { + a = Float(components[3]) + } + + if alpha { + return String(format: "%02lX%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255), lroundf(a * 255)) + } else { + return String(format: "%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255)) + } + } } diff --git a/openHABCore/Sources/Util/UnknownCaseRepresentable.swift b/openHABCore/Sources/Util/UnknownCaseRepresentable.swift new file mode 100644 index 000000000..244899033 --- /dev/null +++ b/openHABCore/Sources/Util/UnknownCaseRepresentable.swift @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +// Graciously handling of unknown enum types: https://www.latenightswift.com/2019/02/04/unknown-enum-cases/ +protocol UnknownCaseRepresentable: RawRepresentable, CaseIterable where RawValue: Equatable { + static var unknownCase: Self { get } +} + +extension UnknownCaseRepresentable { + public init(rawValue: RawValue) { + let value = Self.allCases.first { $0.rawValue == rawValue } + self = value ?? Self.unknownCase + } +} diff --git a/openHABTestsSwift/NumberStateTest.swift b/openHABTestsSwift/NumberStateTest.swift new file mode 100644 index 000000000..b49412d77 --- /dev/null +++ b/openHABTestsSwift/NumberStateTest.swift @@ -0,0 +1,90 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import XCTest + +@testable import openHAB +@testable import OpenHABCore + +class NumberStateTest: XCTestCase { + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testNumberState() throws { + XCTAssertEqual(NumberState(value: 100.3, format: "%d").toString(locale: nil), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%d").toString(locale: Locale(identifier: "US")), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%d").toString(locale: Locale(identifier: "US")), "100") + XCTAssertEqual(NumberState(value: 100.4, format: "%.1f").toString(locale: Locale(identifier: "US")), "100.4") + XCTAssertEqual(NumberState(value: 100.4, format: "%.1f").toString(locale: Locale(identifier: "de")), "100,4") + XCTAssertEqual(NumberState(value: 100.4, unit: "K", format: "%.1f %unit%").toString(locale: Locale(identifier: "US")), "100.4 K") + XCTAssertEqual(NumberState(value: 100.4, unit: "", format: "%.1f %unit%").toString(locale: Locale(identifier: "US")), "100.4 ") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: nil).toString(locale: Locale(identifier: "US")), "100.4 °C") + XCTAssertEqual(NumberState(value: 100.4, unit: nil, format: nil).toString(locale: Locale(identifier: "US")), "100.4") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: "%.1f %unit%").toString(locale: Locale(identifier: "de")), "100,4 °C") + XCTAssertEqual(NumberState(value: 100.4, unit: "°C", format: "%,.1f %unit%").toString(locale: Locale(identifier: "de")), ",.1f °C") // %,.1f is an unvalid format string in Swift + } + + func testToItemType() throws { + XCTAssertEqual("NumberItem".toItemType(), OpenHABItem.ItemType.number) + XCTAssertEqual("Number:Temperature".toItemType(), OpenHABItem.ItemType.numberWithDimension) + XCTAssertEqual("String".toItemType(), OpenHABItem.ItemType.stringItem) + XCTAssertEqual("blabla".toItemType(), nil) + } + + func testToWidgetType() throws { + XCTAssertEqual("Colorpicker".toWidgetType(), OpenHABWidget.WidgetType.colorpicker) + XCTAssertEqual("colorpicker".toWidgetType(), OpenHABWidget.WidgetType.unknown) + } + + func testParseAs() throws { + XCTAssertEqual("ON".parseAsBool(), true) + XCTAssertEqual("4,3,1".parseAsBrightness(), 1) + XCTAssertEqual("4,31".parseAsBrightness(), nil) + XCTAssertEqual("4,3,0".parseAsBool(), false) + XCTAssertEqual("4,3,1".parseAsBool(), true) + XCTAssertEqual("1".parseAsBool(), true) + XCTAssertEqual("0".parseAsBool(), false) + XCTAssertEqual("ON".parseAsNumber(), NumberState(value: 100.0)) + XCTAssertEqual("OFF".parseAsNumber(), NumberState(value: 0.0)) + XCTAssertEqual("24.4 °F".parseAsNumber(), NumberState(value: 24.4, unit: "°F", format: nil)) + XCTAssertEqual("24.4 °F".parseAsNumber(format: "%.f"), NumberState(value: 24.4, unit: "°F", format: "%.f")) + let col1 = "Uninitialized".parseAsUIColor() + let col2 = UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 1.0) + XCTAssert(col1!.equals(col2)) + XCTAssertEqual("360,100,100".parseAsUIColor(), UIColor(hue: CGFloat(state: "360", divisor: 360), saturation: CGFloat(state: "100", divisor: 100), brightness: CGFloat(state: "100", divisor: 100), alpha: 1.0)) + } +} + +extension UIColor { + func equals(_ rhs: UIColor) -> Bool { + var lhsR: CGFloat = 0 + var lhsG: CGFloat = 0 + var lhsB: CGFloat = 0 + var lhsA: CGFloat = 0 + getRed(&lhsR, green: &lhsG, blue: &lhsB, alpha: &lhsA) + + var rhsR: CGFloat = 0 + var rhsG: CGFloat = 0 + var rhsB: CGFloat = 0 + var rhsA: CGFloat = 0 + rhs.getRed(&rhsR, green: &rhsG, blue: &rhsB, alpha: &rhsA) + + return lhsR == rhsR && + lhsG == rhsG && + lhsB == rhsB && + lhsA == rhsA + } +} diff --git a/openHABTestsSwift/OpenHABGeneralTests.swift b/openHABTestsSwift/OpenHABGeneralTests.swift index 781ef60a4..dc0b4a223 100644 --- a/openHABTestsSwift/OpenHABGeneralTests.swift +++ b/openHABTestsSwift/OpenHABGeneralTests.swift @@ -44,7 +44,7 @@ class OpenHABGeneralTests: XCTestCase { let urlc = Endpoint.icon(rootUrl: "http://192.169.2.1", version: 2, icon: "switch", - value: "OFF", + state: "OFF", 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 a95cd5062..d2bee0859 100644 --- a/openHABTestsSwift/OpenHABJSONParserTests.swift +++ b/openHABTestsSwift/OpenHABJSONParserTests.swift @@ -529,6 +529,7 @@ class OpenHABJSONParserTests: XCTestCase { } """ let data = Data(json.utf8) + do { var widget: OpenHABWidget widget = try { @@ -544,8 +545,24 @@ class OpenHABJSONParserTests: XCTestCase { } } -// func testUserData() { -// let userData = UserData() -// XCTAssertEqual(userData.items[0].widgetId, "00") -// } + func testServerVersion() { + let json = """ + {"version":"3", "links":[{"type":"uuid","url":"http://192.168.2.15:8081/rest/uuid"}, + {"type":"audio","url":"http://192.168.2.15:8081/rest/audio"},{"type":"bindings","url":"http://192.168.2.15:8081/rest/bindings"},{"type":"channel-types","url":"http://192.168.2.15:8081/rest/channel-types"},{"type":"config-descriptions","url":"http://192.168.2.15:8081/rest/config-descriptions"},{"type":"discovery","url":"http://192.168.2.15:8081/rest/discovery"}, + {"type":"inbox","url":"http://192.168.2.15:8081/rest/inbox"},{"type":"extensions","url":"http://192.168.2.15:8081/rest/extensions"},{"type":"items","url":"http://192.168.2.15:8081/rest/items"},{"type":"links","url":"http://192.168.2.15:8081/rest/links"},{"type":"persistence","url":"http://192.168.2.15:8081/rest/persistence"},{"type":"profile-types","url":"http://192.168.2.15:8081/rest/profile-types"},{"type":"services","url":"http://192.168.2.15:8081/rest/services"}, + {"type":"things","url":"http://192.168.2.15:8081/rest/things"},{"type":"thing-types","url":"http://192.168.2.15:8081/rest/thing-types"},{"type":"sitemaps","url":"http://192.168.2.15:8081/rest/sitemaps"},{"type":"voice","url":"http://192.168.2.15:8081/rest/voice"},{"type":"iconsets","url":"http://192.168.2.15:8081/rest/iconsets"},{"type":"habpanel","url":"http://192.168.2.15:8081/rest/habpanel"}]} + """ + let data = Data(json.utf8) + do { + // var widget: OpenHABServerLinks + let properties = try decoder.decode(OpenHABServerProperties.self, from: data) + + XCTAssertEqual(properties.version, "3", "Checking version") + XCTAssertEqual(properties.links[0].type, "uuid", "Checking finding links") + XCTAssertEqual(properties.linkUrl(byType: "uuid"), "http://192.168.2.15:8081/rest/uuid", "Checking finding link by type") + + } catch { + XCTFail("Whoops, an error occured: \(error)") + } + } } diff --git a/openHABTestsSwift/OpenHABXMLParserTests.swift b/openHABTestsSwift/OpenHABXMLParserTests.swift index 74c63fa9e..91fc1fb23 100644 --- a/openHABTestsSwift/OpenHABXMLParserTests.swift +++ b/openHABTestsSwift/OpenHABXMLParserTests.swift @@ -27,9 +27,6 @@ class OpenHABXMLParserTests: XCTestCase { } func testFuziParser() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - let xml = """ NumberItem @@ -43,7 +40,7 @@ class OpenHABXMLParserTests: XCTestCase { let document = try XMLDocument(data: xml) if let root = document.root { let item = OpenHABItem(xml: root) - XCTAssertEqual(item.type, "NumberItem") + XCTAssertEqual(item.type, .number) } else { throw TestingError.noXMLDocument } diff --git a/openHABTestsSwift/ParseAsTest.swift b/openHABTestsSwift/ParseAsTest.swift new file mode 100644 index 000000000..b8a7f7ea6 --- /dev/null +++ b/openHABTestsSwift/ParseAsTest.swift @@ -0,0 +1,33 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import XCTest + +@testable import openHAB +@testable import OpenHABCore + +class ParseAsTest: XCTestCase { + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + + XCTAssertFalse("10,10,0".parseAsBool()) + XCTAssertTrue("10,10,50".parseAsBool()) + } +} diff --git a/openHABTestsSwift/restAPI.json b/openHABTestsSwift/restAPI.json new file mode 100644 index 000000000..d122a4c74 --- /dev/null +++ b/openHABTestsSwift/restAPI.json @@ -0,0 +1,31 @@ +{"name":"testUoM", + "label":"testUoM", + "link":"http://192.168.2.15:8081/rest/sitemaps/testUoM", + "homepage":{ + "id":"testing", + "title":"testUoM","link":"http://192.168.2.15:8081/rest/sitemaps/testing/testing","leaf":false,"timeout":false, + "widgets": + [{"widgetId":"00", + "type":"Frame", + "visibility":true, + "label":"Statistik", + "icon":"frame", + "mappings":[], + "widgets": + [{"widgetId":"0000", + "type":"Setpoint", + "visibility":true, + "label":"Time in minutes for sitemap [40.0 min]", + "icon":"number", + "mappings":[], + "minValue":5, + "maxValue":60, + "step":5, + "item":{"link":"http://192.168.2.15:8081/rest/items/iSomeUoMItem", + "state":"40 min", + "stateDescription":{ + "pattern":"%,.1f s", + "readOnly":false, + "options":[]}, + "type":"Number:Time", + "name":"iSomeUoMItem","label":"Time in seconds from/to actor DPT 7.005","tags":[],"groupNames":[]},"widgets":[]}]}]}} diff --git a/openHABWatch Extension/OpenHABWatchTracker.swift b/openHABWatch Extension/OpenHABWatchTracker.swift index c4f0e13aa..65f69e9fe 100644 --- a/openHABWatch Extension/OpenHABWatchTracker.swift +++ b/openHABWatch Extension/OpenHABWatchTracker.swift @@ -40,6 +40,7 @@ class OpenHABWatchTracker: NSObject { } func start() { + #if !os(watchOS) oldReachabilityStatus = pathMonitor.currentPath pathMonitor.pathUpdateHandler = { [weak self] path in guard let self = self else { return } @@ -47,7 +48,7 @@ class OpenHABWatchTracker: NSObject { let nStatus = path if nStatus != self.oldReachabilityStatus { if let oldReachabilityStatus = self.oldReachabilityStatus { - os_log("Network status changed from %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, self.string(from: oldReachabilityStatus) ?? "", self.string(from: nStatus) ?? "") + os_log("Network status changed from %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, oldReachabilityStatus.debugDescription, nStatus.debugDescription) } self.oldReachabilityStatus = nStatus (self.delegate as? OpenHABWatchTrackerExtendedDelegate)?.openHABTrackingNetworkChange(nStatus) @@ -58,7 +59,7 @@ class OpenHABWatchTracker: NSObject { } } pathMonitor.start(queue: backgroundQueue) - + #endif selectUrl() } @@ -67,6 +68,31 @@ class OpenHABWatchTracker: NSObject { } func selectUrl() { + #if os(watchOS) + if ObservableOpenHABDataObject.shared.localUrl.isEmpty { + os_log("Starting discovery", log: .default, type: .debug) + startDiscovery() + } else { + if let connectivityTask = connectivityTask { + connectivityTask.cancel() + } + let request = URLRequest(url: URL(string: ObservableOpenHABDataObject.shared.localUrl)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 2.0) + connectivityTask = NetworkConnection.shared.manager.request(request) + .validate(statusCode: 200 ..< 300) + .responseData { response in + switch response.result { + case .success: + os_log("Tracking local URL", log: .default, type: .debug) + self.trackedLocalUrl() + case .failure: + os_log("Tracking remote URL", log: .default, type: .debug) + self.trackedRemoteUrl() + } + } + connectivityTask?.resume() + } + #else + // Check if any network is available if isNetworkConnected() { // Check if network is WiFi. If not, go for remote URL @@ -103,6 +129,7 @@ class OpenHABWatchTracker: NSObject { let trackingError = NSError(domain: "openHAB", code: 100, userInfo: errorDetail as? [String: Any]) delegate?.openHABTrackingError(trackingError) } + #endif } func trackedLocalUrl() { @@ -113,7 +140,7 @@ class OpenHABWatchTracker: NSObject { func trackedRemoteUrl() { let openHABUrl = normalizeUrl(ObservableOpenHABDataObject.shared.remoteUrl) - if (openHABUrl?.count ?? 0) > 0 { + if !(openHABUrl ?? "").isEmpty { // delegate?.openHABTrackingProgress("Connecting to remote URL") trackedUrl(URL(string: openHABUrl!)) } else { @@ -253,14 +280,16 @@ class OpenHABWatchTracker: NSObject { func isNetworkWiFi() -> Bool { (pathMonitor.currentPath.status == .satisfied && !pathMonitor.currentPath.isExpensive) } +} - func string(from path: NWPath) -> String? { - switch path.status { +extension NWPath: CustomStringConvertible { + public var description: String { + switch status { case .unsatisfied, .requiresConnection: return "unreachable" case .satisfied: var str = "reachable:" - for interface in path.availableInterfaces { + for interface in availableInterfaces { switch interface.type { case .wifi: str += " wifi" diff --git a/openHABWatch Extension/PreferencesHostingController.swift b/openHABWatch Extension/PreferencesHostingController.swift index f6566ce2c..5356e5b7b 100644 --- a/openHABWatch Extension/PreferencesHostingController.swift +++ b/openHABWatch Extension/PreferencesHostingController.swift @@ -9,6 +9,7 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCoreWatch import SwiftUI import WatchKit diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index 16d299cd9..60feaa0c5 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -43,12 +43,12 @@ struct ContentView: View { buttons: [.default(Text(NSLocalizedString("abort", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .deny }, - .default(Text(NSLocalizedString("once", comment: ""))) { + .default(Text(NSLocalizedString("once", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitOnce }, - .default(Text(NSLocalizedString("always", comment: ""))) { + .default(Text(NSLocalizedString("always", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitAlways - }]) + }]) } } @@ -74,7 +74,7 @@ struct ContentView: View { return AnyView(ImageRow(URL: URL(string: widget.url))) } case .chart: - let url = Endpoint.chart(rootUrl: settings.openHABRootUrl, period: widget.period, type: widget.item?.type, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: .dark).url + let url = Endpoint.chart(rootUrl: settings.openHABRootUrl, period: widget.period, type: widget.item?.type ?? .none, service: widget.service, name: widget.item?.name, legend: widget.legend, theme: .dark).url return AnyView(ImageRow(URL: url)) case .mapview: return AnyView(MapViewRow(widget: widget)) diff --git a/openHABWatch Extension/Views/Rows/GenericRow.swift b/openHABWatch Extension/Views/Rows/GenericRow.swift index 7fb0cb0d5..a3305db8f 100644 --- a/openHABWatch Extension/Views/Rows/GenericRow.swift +++ b/openHABWatch Extension/Views/Rows/GenericRow.swift @@ -56,7 +56,7 @@ extension ObservableOpenHABWidget { // ContentView(viewModel: UserData(url: URL(string: pageUrl)), // settings: settings) ) { - Image(systemName: "chevron.right") + Image(systemName: "chevron.right") }) } else { diff --git a/openHABWatch Extension/Views/Rows/ImageRawRow.swift b/openHABWatch Extension/Views/Rows/ImageRawRow.swift index 01fe0126b..44e0c0d93 100644 --- a/openHABWatch Extension/Views/Rows/ImageRawRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRawRow.swift @@ -21,7 +21,7 @@ struct ImageRawRow: View { var body: some View { var imageView: some View { - if let data = widget.item?.state.components(separatedBy: ",")[safe: 1], + if let data = widget.item?.state?.components(separatedBy: ",")[safe: 1], let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters), let image = UIImage(data: decodedData) { return AnyView(Image(uiImage: image) diff --git a/openHABWatch Extension/Views/Rows/ImageRow.swift b/openHABWatch Extension/Views/Rows/ImageRow.swift index 560f8d2d9..f9af4bcb6 100644 --- a/openHABWatch Extension/Views/Rows/ImageRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRow.swift @@ -42,7 +42,7 @@ struct ImageRow_Previews: PreviewProvider { let iconURL = Endpoint.icon(rootUrl: PreviewConstants.remoteURLString, version: 2, icon: "Switch", - value: "ON", + state: "ON", iconType: .png).url // let widget = UserData().widgets[8] return ImageRow(URL: iconURL) diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index 750e46c0c..99a0a6cf9 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -24,7 +24,7 @@ struct SegmentRow: View { guard case let .segmented(value) = self.widget.stateEnumBinding else { return 0 } return value }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) // self.widget.sendCommand($0) self.widget.stateEnumBinding = .segmented($0) diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index 3e4792188..13c63c9ce 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -37,7 +37,7 @@ struct SetpointRow: View { EncircledIconWithAction(systemName: "chevron.down.circle.fill", - action: self.decreaseValue) + action: self.decreaseValue) Spacer() @@ -54,43 +54,28 @@ struct SetpointRow: View { } } - func decreaseValue() { - os_log("down button pressed", log: .viewCycle, type: .info) - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() - widget.step - newValue = max(newValue, widget.minValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() - Int(widget.step) - newValue = max(newValue, Int(widget.minValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } + private func handleUpDown(down: Bool) { + var numberState = widget.stateValueAsNumberState + let stateValue = numberState?.value ?? widget.minValue + let newValue: Double + switch down { + case true: + newValue = stateValue - widget.step + case false: + newValue = stateValue + widget.step + } + if newValue >= widget.minValue, newValue <= widget.maxValue { + numberState?.value = newValue + widget.sendItemUpdate(state: numberState) } } - func increaseValue() { - os_log("up button pressed", log: .viewCycle, type: .info) + func decreaseValue() { + handleUpDown(down: true) + } - if let item = widget.item { - if item.state == "Uninitialized" { - widget.sendCommandDouble(widget.minValue) - } else { - if !isIntStep { - var newValue = item.stateAsDouble() + widget.step - newValue = min(newValue, widget.maxValue) - widget.sendCommand(newValue.valueText(step: widget.step)) - } else { - var newValue = item.stateAsInt() + Int(widget.step) - newValue = min(newValue, Int(widget.maxValue)) - widget.sendCommand(String(format: "%ld", newValue)) - } - } - } + func increaseValue() { + handleUpDown(down: false) } } diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index a2227f142..03e5b8ea3 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -20,13 +20,13 @@ struct SliderRow: View { var body: some View { let valueBinding = Binding(get: { - guard case let .slider(value) = self.widget.stateEnumBinding else { return 0 } - return value + self.widget.adjustedValue }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) self.widget.sendCommand($0.valueText(step: self.widget.step)) - self.widget.stateEnumBinding = .slider($0) + + // self.widget.stateEnumBinding = .slider($0) }) return diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index 64c592509..0ec3fb93f 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -24,7 +24,7 @@ struct SwitchRow: View { let stateBinding = Binding(get: { self.widget.stateEnumBinding.boolState }, - set: { + set: { if $0 { os_log("Switch to ON", log: .viewCycle, type: .info) self.widget.sendCommand("ON") diff --git a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift index c133443ae..1c1cf7980 100644 --- a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift @@ -20,7 +20,7 @@ struct DetailTextLabelView: View { Text($0) .font(.footnote) .lineLimit(1) - .foregroundColor(self.widget.valuecolor != "" ? Color(fromString: self.widget.valuecolor) : .secondary) + .foregroundColor(!self.widget.valuecolor.isEmpty ? Color(fromString: self.widget.valuecolor) : .secondary) } } } diff --git a/openHABWatch Extension/Views/Utils/IconView.swift b/openHABWatch Extension/Views/Utils/IconView.swift index 349e3587c..bb421d12c 100644 --- a/openHABWatch Extension/Views/Utils/IconView.swift +++ b/openHABWatch Extension/Views/Utils/IconView.swift @@ -23,7 +23,7 @@ struct IconView: View { Endpoint.icon(rootUrl: settings.openHABRootUrl, version: 2, icon: widget.icon, - value: widget.item?.state ?? "", + state: widget.item?.state ?? "", iconType: .png).url } diff --git a/openHABWatch Extension/Views/Utils/TextLabelView.swift b/openHABWatch Extension/Views/Utils/TextLabelView.swift index 4b46c44f8..98cbd02b5 100644 --- a/openHABWatch Extension/Views/Utils/TextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/TextLabelView.swift @@ -19,7 +19,7 @@ struct TextLabelView: View { Text(widget.labelText ?? "") .font(.caption) .lineLimit(2) - .foregroundColor(widget.labelcolor != "" ? Color(fromString: widget.labelcolor) : .primary) + .foregroundColor(!widget.labelcolor.isEmpty ? Color(fromString: widget.labelcolor) : .primary) } } diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift index 3b233a688..248982906 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABDataObject.swift @@ -13,28 +13,6 @@ import Combine import Foundation import OpenHABCoreWatch -@propertyWrapper -struct UserDefault { - let key: String - let defaultValue: T - // https://www.swiftbysundell.com/articles/property-wrappers-in-swift/ - var storage: UserDefaults = .standard - - public var wrappedValue: T { - get { - storage.object(forKey: key) as? T ?? defaultValue - } - set { - storage.set(newValue, forKey: key) - } - } - - init(_ key: String, defaultValue: T) { - self.key = key - self.defaultValue = defaultValue - } -} - final class ObservableOpenHABDataObject: DataObject, ObservableObject { static let shared = ObservableOpenHABDataObject() @@ -43,49 +21,49 @@ final class ObservableOpenHABDataObject: DataObject, ObservableObject { let objectWillChange = PassthroughSubject() let objectRefreshed = PassthroughSubject() - @UserDefault("rootUrl", defaultValue: "") + @UserDefaultsBacked(key: "rootUrl", defaultValue: "") var openHABRootUrl: String { willSet { objectWillChange.send() } } - @UserDefault("localUrl", defaultValue: "") + @UserDefaultsBacked(key: "localUrl", defaultValue: "") var localUrl: String { willSet { objectWillChange.send() } } - @UserDefault("remoteUrl", defaultValue: "") + @UserDefaultsBacked(key: "remoteUrl", defaultValue: "") var remoteUrl: String { willSet { objectWillChange.send() } } - @UserDefault("sitemapName", defaultValue: "") + @UserDefaultsBacked(key: "sitemapName", defaultValue: "") var sitemapName: String { willSet { objectWillChange.send() } } - @UserDefault("username", defaultValue: "") + @UserDefaultsBacked(key: "username", defaultValue: "") var openHABUsername: String { willSet { objectWillChange.send() } } - @UserDefault("password", defaultValue: "") + @UserDefaultsBacked(key: "password", defaultValue: "") var openHABPassword: String { willSet { objectWillChange.send() } } - @UserDefault("ignoreSSL", defaultValue: true) + @UserDefaultsBacked(key: "ignoreSSL", defaultValue: true) var ignoreSSL: Bool { willSet { objectWillChange.send() @@ -93,14 +71,14 @@ final class ObservableOpenHABDataObject: DataObject, ObservableObject { } } - @UserDefault("alwaysSendCreds", defaultValue: false) + @UserDefaultsBacked(key: "alwaysSendCreds", defaultValue: false) var openHABAlwaysSendCreds: Bool { willSet { objectWillChange.send() } } - @UserDefault("haveReceivedAppContext", defaultValue: false) + @UserDefaultsBacked(key: "haveReceivedAppContext", defaultValue: false) var haveReceivedAppContext: Bool { didSet { objectRefreshed.send() diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift index 75b574537..6780a73e9 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift @@ -102,7 +102,7 @@ extension ObservableOpenHABSitemapPage { extension ObservableOpenHABSitemapPage.CodingData { var openHABSitemapPage: ObservableOpenHABSitemapPage { - let mappedWidgets = widgets?.map { $0.openHABWidget } ?? [] + let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] return ObservableOpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) } } diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 3544f6bb4..92813a942 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -19,9 +19,9 @@ import MapKit import OpenHABCoreWatch import os.log -enum StateEnum { +enum WidgetTypeEnum { case switcher(Bool) - case slider(Double) + case slider // case segmented(Int) case unassigned case rollershutter @@ -71,8 +71,10 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO var mappings: [OpenHABWidgetMapping] = [] var image: UIImage? var widgets: [ObservableOpenHABWidget] = [] + public var visibility = true + public var switchSupport = false - @Published var stateEnumBinding: StateEnum = .unassigned + @Published var stateEnumBinding: WidgetTypeEnum = .unassigned // Text prior to "[" var labelText: String? { @@ -101,6 +103,22 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } + public var stateValueAsBool: Bool? { + item?.state?.parseAsBool() + } + + public var stateValueAsBrightness: Int? { + item?.state?.parseAsBrightness() + } + + public var stateValueAsUIColor: UIColor? { + item?.state?.parseAsUIColor() + } + + public var stateValueAsNumberState: NumberState? { + item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) + } + var adjustedValue: Double { if let item = item { return adj(item.stateAsDouble()) @@ -109,7 +127,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } - var stateEnum: StateEnum { + var stateEnum: WidgetTypeEnum { switch type { case "Frame": return .frame @@ -117,12 +135,11 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 if !mappings.isEmpty { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) - // RollershutterItem changed to Rollershutter in later builds of OH2 - } else if let type = item?.type, type == "Switch" { + } else if item?.isOfTypeOrGroupType(.switchItem) ?? false { return .switcher(item?.state == "ON" ? true : false) - } else if let type = item?.type, type.isAny(of: "RollershutterItem", "Rollershutter") || (type == "Group" && item?.groupType == "Rollershutter") { + } else if item?.isOfTypeOrGroupType(.rollershutter) ?? false { return .rollershutter - } else if item?.stateDescription?.options.count ?? 0 > 0 { + } else if !mappingsOrItemOptions.isEmpty { return .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) } else { return .switcher(item?.state == "ON" ? true : false) @@ -130,7 +147,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO case "Setpoint": return .setpoint case "Slider": - return .slider(adjustedValue) + return .slider // (adjustedValue) case "Selection": return .selection case "Colorpicker": @@ -150,6 +167,20 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO } } + public func sendItemUpdate(state: NumberState?) { + guard let item = item, let state = state else { + os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) + return + } + if item.isOfTypeOrGroupType(.numberWithDimension) { + // For number items, include unit (if present) in command + sendCommand(state.toString(locale: Locale(identifier: "US"))) + } else { + // For all other items, send the plain value + sendCommand(state.formatValue()) + } + } + func sendCommandDouble(_ command: Double) { sendCommand(String(command)) } @@ -298,7 +329,7 @@ extension ObservableOpenHABWidget { // swiftlint:disable line_length extension ObservableOpenHABWidget.CodingData { var openHABWidget: ObservableOpenHABWidget { - let mappedWidgets = widgets.map { $0.openHABWidget } + let mappedWidgets = widgets.map(\.openHABWidget) return ObservableOpenHABWidget(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) } } diff --git a/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift b/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift new file mode 100644 index 000000000..fa0de07a4 --- /dev/null +++ b/openHABWatch Extension/openHABWatch Extension/Model/UserDefaultsBacked.swift @@ -0,0 +1,36 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +@propertyWrapper +struct UserDefaultsBacked { + let key: String + let defaultValue: T + // https://www.swiftbysundell.com/articles/property-wrappers-in-swift/ + var storage: UserDefaults = .standard + + public var wrappedValue: T { + get { + storage.object(forKey: key) as? T ?? defaultValue + } + set { + storage.set(newValue, forKey: key) + } + } +} + +/// Convenience initializer when UserDefaults is optional. +extension UserDefaultsBacked where T: ExpressibleByNilLiteral { + init(key: String, storage: UserDefaults = .standard) { + self.init(key: key, defaultValue: nil, storage: storage) + } +} diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index ef91474c2..0b639a67c 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -97,14 +97,6 @@ final class UserData: ObservableObject { refreshUrl() } - func loadPage(urlString: String, - longPolling: Bool, - refresh: Bool, - sitemapName: String = "watch") { - let url = Endpoint.watchSitemap(openHABRootUrl: urlString, sitemapName: sitemapName).url - loadPage(url: url, longPolling: longPolling, refresh: refresh) - } - func request(_ endpoint: Endpoint) -> OpenHABCoreWatch.Future { // Start by constructing a Promise, that will later be // returned as a Future @@ -125,37 +117,23 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: true, openHABVersion: 2) { [weak self] response in - guard self != nil else { return } + guard self != nil else { return } - switch response.result { - case .success: - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - promise.resolve(with: response.result.value ?? Data()) + switch response.result { + case .success: + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + promise.resolve(with: response.result.value ?? Data()) - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - promise.reject(with: error) - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + promise.reject(with: error) + } } currentPageOperation?.resume() return promise } - func loadPage(_ endpoint: Endpoint) { - request(endpoint) - .decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - .trafo() - .observe { result in - switch result { - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@", log: .remoteAccess, type: .error, error.localizedDescription) - case let .success(page): - self.openHABSitemapPage = page - } - } - } - func loadPage(url: URL?, longPolling: Bool, refresh: Bool) { @@ -167,44 +145,44 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: longPolling, openHABVersion: 2) { [weak self] response in - guard let self = self else { return } - - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - - if let data = response.result.value { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - self.openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + guard let self = self else { return } + + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + + if let data = response.result.value { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + self.openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + } } - } - self.openHABSitemapPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } + self.openHABSitemapPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } - self.widgets = self.openHABSitemapPage?.widgets ?? [] + self.widgets = self.openHABSitemapPage?.widgets ?? [] - self.showAlert = self.widgets.isEmpty ? true : false - if refresh { self.loadPage(url: url, - longPolling: true, - refresh: true) } + self.showAlert = self.widgets.isEmpty ? true : false + if refresh { self.loadPage(url: url, + longPolling: true, + refresh: true) } - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - self.errorDescription = error.localizedDescription - self.widgets = [] - self.showAlert = true - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + self.errorDescription = error.localizedDescription + self.widgets = [] + self.showAlert = true + } } currentPageOperation?.resume() } @@ -226,6 +204,20 @@ final class UserData: ObservableObject { tracker?.selectUrl() } } + + func loadPage(_ endpoint: Endpoint) { + request(endpoint) + .decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + .trafo() + .observe { result in + switch result { + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@", log: .remoteAccess, type: .error, error.localizedDescription) + case let .success(page): + self.openHABSitemapPage = page + } + } + } } extension UserData: OpenHABWatchTrackerDelegate { @@ -241,10 +233,9 @@ extension UserData: OpenHABWatchTrackerDelegate { } ObservableOpenHABDataObject.shared.openHABRootUrl = urlString - loadPage(urlString: urlString, - longPolling: false, - refresh: true, - sitemapName: ObservableOpenHABDataObject.shared.sitemapName) + + let url = Endpoint.watchSitemap(openHABRootUrl: urlString, sitemapName: ObservableOpenHABDataObject.shared.sitemapName).url + loadPage(url: url, longPolling: false, refresh: true) } func openHABTrackingProgress(_ message: String?) { diff --git a/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift b/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift index 12801250c..19a0a5c24 100644 --- a/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift +++ b/openHABWatch Extension/openHABWatch Extension/external/AppMessageService.swift @@ -73,7 +73,7 @@ class AppMessageService: NSObject, WCSessionDelegate { errorHandler: { (error) in os_log("Error sending message %{PUBLIC}@", log: .watch, type: .info, "\(error)") - }) + }) } @available(watchOSApplicationExtension 2.2, *) From f2734dc86b049a3cb4a9bebe8c000eab30bb0de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 16:19:25 +0200 Subject: [PATCH 50/78] Update for cocoapod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index 3f0585e02..638e64867 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -168,4 +168,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 7e3ab1cfad25c0c0ad6f55cd58134ce3b910ec2e -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.0.beta.2 From b0f8a51a21bdb7e57fbb412c221451cab6953736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 16:42:58 +0200 Subject: [PATCH 51/78] Modified Gemfile.lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 62e1e79f3..2a41ba347 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,16 +6,16 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.358.0) - aws-sdk-core (3.104.4) + aws-partitions (1.361.0) + aws-sdk-core (3.105.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.36.0) + aws-sdk-kms (1.37.0) aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.78.0) + aws-sdk-s3 (1.79.1) aws-sdk-core (~> 3, >= 3.104.3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) @@ -44,7 +44,7 @@ GEM faraday_middleware (1.0.0) faraday (~> 1.0) fastimage (2.2.0) - fastlane (2.156.1) + fastlane (2.157.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) @@ -97,7 +97,7 @@ GEM google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.1) - google-cloud-storage (1.27.0) + google-cloud-storage (1.28.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) From ab1812708da32afb8336b5b7217285e71eb088e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 16:47:49 +0200 Subject: [PATCH 52/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index d53b550db..9a892db01 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1999,7 +1999,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2011,7 +2011,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2043,7 +2043,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2055,7 +2055,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2084,7 +2084,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2103,7 +2103,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2132,7 +2132,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2150,7 +2150,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2180,7 +2180,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2198,7 +2198,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2230,7 +2230,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2247,7 +2247,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2278,14 +2278,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2317,14 +2317,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2353,7 +2353,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2365,7 +2365,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2395,7 +2395,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2407,7 +2407,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2437,7 +2437,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2449,7 +2449,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2482,7 +2482,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2494,7 +2494,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2635,7 +2635,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2652,7 +2652,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2682,7 +2682,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410451; + CURRENT_PROJECT_VERSION = 1580410452; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2699,7 +2699,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From ff023b1789615b71d6ebcd417881090dc5fc329b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 18:31:16 +0200 Subject: [PATCH 53/78] upgrade to swiftlint 0.40.1. This allows to drop many // swiftlint:disable file_types_order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- .swiftlint.yml | 7 ++++ Podfile.lock | 4 +- openHAB.xcodeproj/project.pbxproj | 10 +++++ openHAB/OpenHABViewController.swift | 3 +- .../OpenHABJSONParserTests.swift | 1 + openHABWatch Extension/NotificationView.swift | 1 - .../Views/ContentView.swift | 2 +- .../Views/PreferencesSwiftUIView.swift | 1 - .../Views/Rows/ColorPickerRow.swift | 1 - .../Views/Rows/FrameRow.swift | 1 - .../Views/Rows/GenericRow.swift | 38 ------------------- .../Views/Rows/ImageRawRow.swift | 1 - .../Views/Rows/ImageRow.swift | 1 - .../Views/Rows/MapViewRow.swift | 1 - .../Views/Rows/PreferencesRowUIView.swift | 1 - .../Views/Rows/RollershutterRow.swift | 1 - .../Views/Rows/SegmentRow.swift | 1 - .../Views/Rows/SetpointRow.swift | 1 - .../Views/Rows/SliderRow.swift | 1 - .../Views/Rows/SwitchRow.swift | 1 - .../Views/Utils/ColorSelection.swift | 1 - .../Views/Utils/DetailTextLabelView.swift | 1 - .../Views/Utils/EncircledIconWithAction.swift | 1 - .../Views/Utils/IconView.swift | 1 - .../Views/Utils/MapView.swift | 1 - .../Views/Utils/TextLabelView.swift | 1 - .../Model/LazyView.swift | 26 +++++++++++++ .../ObservableOpenHABWidgetExtension.swift | 35 +++++++++++++++++ 28 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 openHABWatch Extension/openHABWatch Extension/Model/LazyView.swift create mode 100644 openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift diff --git a/.swiftlint.yml b/.swiftlint.yml index b73e17202..abaa54ef0 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -18,6 +18,13 @@ opt_in_rules: - private_action - prefer_self_type_over_type_of_self - file_name + - computed_accessors_order + - empty_enum_arguments + - prefer_zero_over_explicit_init + - tuple_pattern + - return_value_from_void_function + - void_function_in_ternary + - only_after_dot disabled_rules: # rule identifiers to exclude from running - force_cast diff --git a/Podfile.lock b/Podfile.lock index 638e64867..ed8fa4953 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -82,7 +82,7 @@ PODS: - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - SwiftFormat/CLI (0.45.2) - - SwiftLint (0.39.2) + - SwiftLint (0.40.1) - SwiftMessages (8.0.0): - SwiftMessages/App (= 8.0.0) - SwiftMessages/App (8.0.0) @@ -163,7 +163,7 @@ SPEC CHECKSUMS: SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63 SwiftFormat: 07a1794c1331daaefc1ca6c2ff1da38ee9ca090a - SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 + SwiftLint: bbfed21bf4451dcbd0f5cdbee44a18e06cf91b12 SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 PODFILE CHECKSUM: 7e3ab1cfad25c0c0ad6f55cd58134ce3b910ec2e diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 9a892db01..477c61264 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -137,6 +137,8 @@ DAC6608D236F771600F4501E /* PreferencesSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608C236F771600F4501E /* PreferencesSwiftUIView.swift */; }; DAC6608F236F80BA00F4501E /* PreferencesRowUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */; }; DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */; }; + DAC9AF4724F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */; }; + DAC9AF4924F966FA006DAE93 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4824F966FA006DAE93 /* LazyView.swift */; }; DACC72E224D00D59007EFAE3 /* NumberStateTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */; }; DADC1EAD24D2CB8B0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; DADC1EAE24D2CB8C0052B8D4 /* NumberState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */; }; @@ -491,6 +493,9 @@ DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesRowUIView.swift; sourceTree = ""; }; DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABWatchTests.swift; sourceTree = ""; }; DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCaseExtension.swift; sourceTree = ""; }; + DAC9AF4424F9540D006DAE93 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = SOURCE_ROOT; }; + DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservableOpenHABWidgetExtension.swift; sourceTree = ""; }; + DAC9AF4824F966FA006DAE93 /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; DACC72E024CE14FB007EFAE3 /* restAPI.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = restAPI.json; sourceTree = ""; }; DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberStateTest.swift; sourceTree = ""; }; DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberState.swift; sourceTree = ""; }; @@ -756,6 +761,8 @@ 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */, 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */, DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */, + DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */, + DAC9AF4824F966FA006DAE93 /* LazyView.swift */, ); name = Model; path = "openHABWatch Extension/Model"; @@ -1026,6 +1033,7 @@ DA4D4DB4233F9ACB00B37E37 /* README.md */, DA4D4E0E2340A00200B37E37 /* Changes.md */, DA817E79234BF39B00C91824 /* CHANGELOG.md */, + DAC9AF4424F9540D006DAE93 /* .swiftlint.yml */, 93F38C62238034BD001B1451 /* openHABCore */, DFB2623018830A3600D3244D /* openHAB */, DA2DC23021F2736C00830730 /* openHABTestsSwift */, @@ -1774,6 +1782,7 @@ buildActionMask = 2147483647; files = ( DA7649DE23FC81A20085CE46 /* Unwrap.swift in Sources */, + DAC9AF4724F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift in Sources */, DAF4581423DC1F5D0018B495 /* AppState.swift in Sources */, DA2E0B0E23DCC153009B0A99 /* MapView.swift in Sources */, DA2E0B1023DCC439009B0A99 /* MapViewRow.swift in Sources */, @@ -1800,6 +1809,7 @@ DAF457A023DA3E1C0018B495 /* SegmentRow.swift in Sources */, DAF4578923D79AA50018B495 /* DetailTextLabelView.swift in Sources */, DA15BFBD23C6726400BD8ADA /* ObservableOpenHABDataObject.swift in Sources */, + DAC9AF4924F966FA006DAE93 /* LazyView.swift in Sources */, DA0776F0234788010086C685 /* UserData.swift in Sources */, DA6587222370C9D8007E2E7F /* PreferencesHostingController.swift in Sources */, DAC6608D236F771600F4501E /* PreferencesSwiftUIView.swift in Sources */, diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index b08ea27ed..4ebd015a5 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -1061,8 +1061,7 @@ extension OpenHABViewController: UITableViewDelegate, UITableViewDataSource { var imageRequest = URLRequest(url: urlc) imageRequest.timeoutInterval = 10.0 - let reportOnResults: ((Swift.Result) -> Void)? = { - result in + let reportOnResults: ((Swift.Result) -> Void)? = { result in switch result { case let .success(value): os_log("Task done for: %{PUBLIC}@", log: .viewCycle, type: .info, value.source.url?.absoluteString ?? "") diff --git a/openHABTestsSwift/OpenHABJSONParserTests.swift b/openHABTestsSwift/OpenHABJSONParserTests.swift index d2bee0859..a45ebc209 100644 --- a/openHABTestsSwift/OpenHABJSONParserTests.swift +++ b/openHABTestsSwift/OpenHABJSONParserTests.swift @@ -14,6 +14,7 @@ import os.signpost import XCTest +// swiftlint:disable type_body_length class OpenHABJSONParserTests: XCTestCase { let decoder = JSONDecoder() diff --git a/openHABWatch Extension/NotificationView.swift b/openHABWatch Extension/NotificationView.swift index 6d5dbcbc1..77fcdcd7a 100644 --- a/openHABWatch Extension/NotificationView.swift +++ b/openHABWatch Extension/NotificationView.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct NotificationView: View { let customTextLabel: String? let customDetailTextLabel: String? diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index 60feaa0c5..45e09c021 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -13,7 +13,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct ContentView: View { @ObservedObject var viewModel: UserData @ObservedObject var settings = ObservableOpenHABDataObject.shared @@ -52,6 +51,7 @@ struct ContentView: View { } } + // swiftlint:enable line_length func rowWidget(widget: ObservableOpenHABWidget) -> AnyView? { switch widget.stateEnum { case .switcher: diff --git a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift index 2ab21e503..07f42e676 100644 --- a/openHABWatch Extension/Views/PreferencesSwiftUIView.swift +++ b/openHABWatch Extension/Views/PreferencesSwiftUIView.swift @@ -14,7 +14,6 @@ import os.log import SwiftUI import WatchConnectivity -// swiftlint:disable file_types_order struct PreferencesSwiftUIView: View { @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/ColorPickerRow.swift b/openHABWatch Extension/Views/Rows/ColorPickerRow.swift index d1c13dac5..dc03e8d2a 100644 --- a/openHABWatch Extension/Views/Rows/ColorPickerRow.swift +++ b/openHABWatch Extension/Views/Rows/ColorPickerRow.swift @@ -12,7 +12,6 @@ import os.log import SwiftUI -// swiftlint:disable file_types_order struct ColorPickerRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/FrameRow.swift b/openHABWatch Extension/Views/Rows/FrameRow.swift index a40f16d50..5bd921f83 100644 --- a/openHABWatch Extension/Views/Rows/FrameRow.swift +++ b/openHABWatch Extension/Views/Rows/FrameRow.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct FrameRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/GenericRow.swift b/openHABWatch Extension/Views/Rows/GenericRow.swift index a3305db8f..bc0814220 100644 --- a/openHABWatch Extension/Views/Rows/GenericRow.swift +++ b/openHABWatch Extension/Views/Rows/GenericRow.swift @@ -12,7 +12,6 @@ import os.log import SwiftUI -// swiftlint:disable file_types_order struct GenericRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared @@ -28,43 +27,6 @@ struct GenericRow: View { } } -// https://medium.com/better-programming/swiftui-navigation-links-and-the-common-pitfalls-faced-505cbfd8029b -struct LazyView: View { - let build: () -> Content - - var body: Content { - build() - } - - init(_ build: @autoclosure @escaping () -> Content) { - self.build = build - } -} - -extension ObservableOpenHABWidget { - func makeView(settings: ObservableOpenHABDataObject) -> AnyView { - if linkedPage != nil { - let title = linkedPage?.title.components(separatedBy: "[")[0] ?? "" - let pageUrl = linkedPage?.link ?? "" - os_log("Selected %{PUBLIC}@", log: .viewCycle, type: .info, pageUrl) - return AnyView( - NavigationLink(destination: - LazyView(// EmptyView() - // ) - ContentView(viewModel: UserData(url: URL(string: pageUrl)), settings: - settings, title: title)) -// ContentView(viewModel: UserData(url: URL(string: pageUrl)), -// settings: settings) - ) { - Image(systemName: "chevron.right") - }) - - } else { - return AnyView(EmptyView()) - } - } -} - struct GenericRow_Previews: PreviewProvider { static var previews: some View { let widget = UserData().widgets[6] diff --git a/openHABWatch Extension/Views/Rows/ImageRawRow.swift b/openHABWatch Extension/Views/Rows/ImageRawRow.swift index 44e0c0d93..0cceb1dde 100644 --- a/openHABWatch Extension/Views/Rows/ImageRawRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRawRow.swift @@ -14,7 +14,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct ImageRawRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/ImageRow.swift b/openHABWatch Extension/Views/Rows/ImageRow.swift index f9af4bcb6..4107d28bc 100644 --- a/openHABWatch Extension/Views/Rows/ImageRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRow.swift @@ -14,7 +14,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct ImageRow: View { @State var URL: URL? diff --git a/openHABWatch Extension/Views/Rows/MapViewRow.swift b/openHABWatch Extension/Views/Rows/MapViewRow.swift index ab51cc583..4e4a50cf8 100644 --- a/openHABWatch Extension/Views/Rows/MapViewRow.swift +++ b/openHABWatch Extension/Views/Rows/MapViewRow.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct MapViewRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/PreferencesRowUIView.swift b/openHABWatch Extension/Views/Rows/PreferencesRowUIView.swift index 9cf984857..b00045fb8 100644 --- a/openHABWatch Extension/Views/Rows/PreferencesRowUIView.swift +++ b/openHABWatch Extension/Views/Rows/PreferencesRowUIView.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct PreferencesRowUIView: View { var label: String var content: String diff --git a/openHABWatch Extension/Views/Rows/RollershutterRow.swift b/openHABWatch Extension/Views/Rows/RollershutterRow.swift index 9622de363..ee8fe8573 100644 --- a/openHABWatch Extension/Views/Rows/RollershutterRow.swift +++ b/openHABWatch Extension/Views/Rows/RollershutterRow.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct RollershutterRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index 99a0a6cf9..dd5732511 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -13,7 +13,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct SegmentRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index 13c63c9ce..46c1606b4 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -12,7 +12,6 @@ import os.log import SwiftUI -// swiftlint:disable file_types_order struct SetpointRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index 03e5b8ea3..9de617117 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -13,7 +13,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct SliderRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index 0ec3fb93f..0c15cf970 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -14,7 +14,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct SwitchRow: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Utils/ColorSelection.swift b/openHABWatch Extension/Views/Utils/ColorSelection.swift index 9072ef0ee..49889b4c3 100644 --- a/openHABWatch Extension/Views/Utils/ColorSelection.swift +++ b/openHABWatch Extension/Views/Utils/ColorSelection.swift @@ -48,7 +48,6 @@ enum DragState { } } -// swiftlint:disable file_types_order struct ColorSelection: View { @GestureState var thumb: DragState = .inactive diff --git a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift index 1c1cf7980..7cf767584 100644 --- a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct DetailTextLabelView: View { @ObservedObject var widget: ObservableOpenHABWidget diff --git a/openHABWatch Extension/Views/Utils/EncircledIconWithAction.swift b/openHABWatch Extension/Views/Utils/EncircledIconWithAction.swift index 33b3e070d..8e1a0f31f 100644 --- a/openHABWatch Extension/Views/Utils/EncircledIconWithAction.swift +++ b/openHABWatch Extension/Views/Utils/EncircledIconWithAction.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct EncircledIconWithAction: View { var systemName: String var action: () -> Void diff --git a/openHABWatch Extension/Views/Utils/IconView.swift b/openHABWatch Extension/Views/Utils/IconView.swift index bb421d12c..94049c745 100644 --- a/openHABWatch Extension/Views/Utils/IconView.swift +++ b/openHABWatch Extension/Views/Utils/IconView.swift @@ -14,7 +14,6 @@ import OpenHABCoreWatch import os.log import SwiftUI -// swiftlint:disable file_types_order struct IconView: View { @ObservedObject var widget: ObservableOpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared diff --git a/openHABWatch Extension/Views/Utils/MapView.swift b/openHABWatch Extension/Views/Utils/MapView.swift index 1954c6132..304a814ab 100644 --- a/openHABWatch Extension/Views/Utils/MapView.swift +++ b/openHABWatch Extension/Views/Utils/MapView.swift @@ -14,7 +14,6 @@ import OpenHABCoreWatch import SwiftUI import UIKit -// swiftlint:disable file_types_order struct MapView: WKInterfaceObjectRepresentable { @ObservedObject var widget: ObservableOpenHABWidget diff --git a/openHABWatch Extension/Views/Utils/TextLabelView.swift b/openHABWatch Extension/Views/Utils/TextLabelView.swift index 98cbd02b5..8e4a2b8d4 100644 --- a/openHABWatch Extension/Views/Utils/TextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/TextLabelView.swift @@ -11,7 +11,6 @@ import SwiftUI -// swiftlint:disable file_types_order struct TextLabelView: View { @ObservedObject var widget: ObservableOpenHABWidget diff --git a/openHABWatch Extension/openHABWatch Extension/Model/LazyView.swift b/openHABWatch Extension/openHABWatch Extension/Model/LazyView.swift new file mode 100644 index 000000000..225f7fbfa --- /dev/null +++ b/openHABWatch Extension/openHABWatch Extension/Model/LazyView.swift @@ -0,0 +1,26 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import SwiftUI + +// https://medium.com/better-programming/swiftui-navigation-links-and-the-common-pitfalls-faced-505cbfd8029b +struct LazyView: View { + let build: () -> Content + + var body: Content { + build() + } + + init(_ build: @autoclosure @escaping () -> Content) { + self.build = build + } +} diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift new file mode 100644 index 000000000..989d610cb --- /dev/null +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift @@ -0,0 +1,35 @@ +// Copyright (c) 2010-2020 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import os.log +import SwiftUI + +extension ObservableOpenHABWidget { + func makeView(settings: ObservableOpenHABDataObject) -> AnyView { + if linkedPage != nil { + let title = linkedPage?.title.components(separatedBy: "[")[0] ?? "" + let pageUrl = linkedPage?.link ?? "" + os_log("Selected %{PUBLIC}@", log: .viewCycle, type: .info, pageUrl) + return AnyView( + NavigationLink(destination: + LazyView( + ContentView(viewModel: UserData(url: URL(string: pageUrl)), settings: + settings, title: title)) + ) { + Image(systemName: "chevron.right") + }) + + } else { + return AnyView(EmptyView()) + } + } +} From 1d900bf1d08b4c3bfe3f7b24d4f4344ddb822832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 18:50:02 +0200 Subject: [PATCH 54/78] Updated swiftformat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- .swiftformat | 2 +- Podfile.lock | 4 +- openHAB.xcodeproj/project.pbxproj | 2 + openHAB/OpenHABViewController.swift | 180 +++++++++--------- .../Views/ContentView.swift | 4 +- .../Views/Rows/SegmentRow.swift | 2 +- .../Views/Rows/SetpointRow.swift | 2 +- .../Views/Rows/SliderRow.swift | 2 +- .../Views/Rows/SwitchRow.swift | 2 +- .../ObservableOpenHABWidgetExtension.swift | 2 +- .../openHABWatch Extension/UserData.swift | 84 ++++---- 11 files changed, 144 insertions(+), 142 deletions(-) diff --git a/.swiftformat b/.swiftformat index 7045766d2..4c0ffc009 100644 --- a/.swiftformat +++ b/.swiftformat @@ -6,7 +6,7 @@ # disabled rules --disable specifiers # see https://github.com/nicklockwood/SwiftFormat/issues/364 --disable redundantParens ---disable wrapMultilineStatementBraces +#--disable wrapMultilineStatementBraces # opt-in rules --enable isEmpty diff --git a/Podfile.lock b/Podfile.lock index ed8fa4953..f527db166 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -81,7 +81,7 @@ PODS: - SideMenu (6.4.9) - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.45.2) + - SwiftFormat/CLI (0.46.0) - SwiftLint (0.40.1) - SwiftMessages (8.0.0): - SwiftMessages/App (= 8.0.0) @@ -162,7 +162,7 @@ SPEC CHECKSUMS: PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63 - SwiftFormat: 07a1794c1331daaefc1ca6c2ff1da38ee9ca090a + SwiftFormat: 4da2465002f4c5514327a4376d7cbb475a6358c8 SwiftLint: bbfed21bf4451dcbd0f5cdbee44a18e06cf91b12 SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 477c61264..2574b2502 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -496,6 +496,7 @@ DAC9AF4424F9540D006DAE93 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = SOURCE_ROOT; }; DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservableOpenHABWidgetExtension.swift; sourceTree = ""; }; DAC9AF4824F966FA006DAE93 /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; + DAC9AF4A24F96B1E006DAE93 /* .swiftformat */ = {isa = PBXFileReference; lastKnownFileType = text; path = .swiftformat; sourceTree = ""; }; DACC72E024CE14FB007EFAE3 /* restAPI.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = restAPI.json; sourceTree = ""; }; DACC72E124D00D59007EFAE3 /* NumberStateTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberStateTest.swift; sourceTree = ""; }; DADC1EAB24D2CB6D0052B8D4 /* NumberState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberState.swift; sourceTree = ""; }; @@ -1034,6 +1035,7 @@ DA4D4E0E2340A00200B37E37 /* Changes.md */, DA817E79234BF39B00C91824 /* CHANGELOG.md */, DAC9AF4424F9540D006DAE93 /* .swiftlint.yml */, + DAC9AF4A24F96B1E006DAE93 /* .swiftformat */, 93F38C62238034BD001B1451 /* openHABCore */, DFB2623018830A3600D3244D /* openHAB */, DA2DC23021F2736C00830730 /* openHABTestsSwift */, diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 4ebd015a5..ca8ec66f9 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -419,106 +419,106 @@ class OpenHABViewController: UIViewController { currentPageOperation = NetworkConnection.page(pageUrl: pageUrl, longPolling: longPolling, openHABVersion: appData?.openHABVersion ?? 2) { [weak self] response in - guard let self = self else { return } + guard let self = self else { return } - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - let headers = response.response?.allHeaderFields + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + let headers = response.response?.allHeaderFields - NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" - if !NetworkConnection.atmosphereTrackingId.isEmpty { - os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) - } - var openHABSitemapPage: OpenHABSitemapPage? - if let data = response.result.value { - // If we are talking to openHAB 1.X, talk XML - if self.appData?.openHABVersion == 1 { - let str = String(decoding: data, as: UTF8.self) - os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) - - guard let doc = try? XMLDocument(data: data) else { return } - if let rootElement = doc.root, let name = rootElement.tag { - os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) - if name == "page" { - openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) - } - } - } else { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" + if !NetworkConnection.atmosphereTrackingId.isEmpty { + os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) + } + var openHABSitemapPage: OpenHABSitemapPage? + if let data = response.result.value { + // If we are talking to openHAB 1.X, talk XML + if self.appData?.openHABVersion == 1 { + let str = String(decoding: data, as: UTF8.self) + os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + + guard let doc = try? XMLDocument(data: data) else { return } + if let rootElement = doc.root, let name = rootElement.tag { + os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) + if name == "page" { + openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) } } + } else { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + } } - self.currentPage = openHABSitemapPage - if self.isFiltering { - self.filterContentForSearchText(self.search.searchBar.text) - } + } + self.currentPage = openHABSitemapPage + if self.isFiltering { + self.filterContentForSearchText(self.search.searchBar.text) + } - self.currentPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - self.widgetTableView.reloadData() - UIApplication.shared.isNetworkActivityIndicatorVisible = false - self.refreshControl?.endRefreshing() - self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] - self.loadPage(true) - 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 { - os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) - self.loadPage(false) - } else if (error as NSError?)?.code == -999 { - os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) - } else { - // Error - DispatchQueue.main.async { - if (error as NSError?)?.code == -1012 { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view - } - } else { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view - } + self.currentPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } + self.widgetTableView.reloadData() + UIApplication.shared.isNetworkActivityIndicatorVisible = false + self.refreshControl?.endRefreshing() + self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] + self.loadPage(true) + 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 { + os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) + self.loadPage(false) + } else if (error as NSError?)?.code == -999 { + os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) + } else { + // Error + DispatchQueue.main.async { + if (error as NSError?)?.code == -1012 { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } + } else { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view } } } } + } } currentPageOperation?.resume() diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index 45e09c021..65a64b5ae 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -42,10 +42,10 @@ struct ContentView: View { buttons: [.default(Text(NSLocalizedString("abort", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .deny }, - .default(Text(NSLocalizedString("once", comment: ""))) { + .default(Text(NSLocalizedString("once", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitOnce }, - .default(Text(NSLocalizedString("always", comment: ""))) { + .default(Text(NSLocalizedString("always", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitAlways }]) } diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index dd5732511..fce5d0e74 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -23,7 +23,7 @@ struct SegmentRow: View { guard case let .segmented(value) = self.widget.stateEnumBinding else { return 0 } return value }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) // self.widget.sendCommand($0) self.widget.stateEnumBinding = .segmented($0) diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index 46c1606b4..d91880368 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -36,7 +36,7 @@ struct SetpointRow: View { EncircledIconWithAction(systemName: "chevron.down.circle.fill", - action: self.decreaseValue) + action: self.decreaseValue) Spacer() diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index 9de617117..d5c216fc6 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -21,7 +21,7 @@ struct SliderRow: View { let valueBinding = Binding(get: { self.widget.adjustedValue }, - set: { + set: { os_log("Slider new value = %g", log: .default, type: .info, $0) self.widget.sendCommand($0.valueText(step: self.widget.step)) diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index 0c15cf970..5ba22b685 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -23,7 +23,7 @@ struct SwitchRow: View { let stateBinding = Binding(get: { self.widget.stateEnumBinding.boolState }, - set: { + set: { if $0 { os_log("Switch to ON", log: .viewCycle, type: .info) self.widget.sendCommand("ON") diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift index 989d610cb..aa9bc466d 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift @@ -25,7 +25,7 @@ extension ObservableOpenHABWidget { ContentView(viewModel: UserData(url: URL(string: pageUrl)), settings: settings, title: title)) ) { - Image(systemName: "chevron.right") + Image(systemName: "chevron.right") }) } else { diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 0b639a67c..11af9b4e3 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -117,17 +117,17 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: true, openHABVersion: 2) { [weak self] response in - guard self != nil else { return } + guard self != nil else { return } - switch response.result { - case .success: - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - promise.resolve(with: response.result.value ?? Data()) + switch response.result { + case .success: + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + promise.resolve(with: response.result.value ?? Data()) - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - promise.reject(with: error) - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + promise.reject(with: error) + } } currentPageOperation?.resume() @@ -145,44 +145,44 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: longPolling, openHABVersion: 2) { [weak self] response in - guard let self = self else { return } - - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - - if let data = response.result.value { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - self.openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) - } - } + guard let self = self else { return } + + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - self.openHABSitemapPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) + if let data = response.result.value { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + self.openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } + } - self.widgets = self.openHABSitemapPage?.widgets ?? [] + self.openHABSitemapPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } - self.showAlert = self.widgets.isEmpty ? true : false - if refresh { self.loadPage(url: url, - longPolling: true, - refresh: true) } + self.widgets = self.openHABSitemapPage?.widgets ?? [] - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - self.errorDescription = error.localizedDescription - self.widgets = [] - self.showAlert = true - } + self.showAlert = self.widgets.isEmpty ? true : false + if refresh { self.loadPage(url: url, + longPolling: true, + refresh: true) } + + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + self.errorDescription = error.localizedDescription + self.widgets = [] + self.showAlert = true + } } currentPageOperation?.resume() } From d439af417f2bb863a35be3e142311711a5afa8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 22:24:31 +0200 Subject: [PATCH 55/78] Localization in OpenHABDrawerTableViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- .swiftformat | 3 +- Gemfile.lock | 2 +- openHAB/NewImageUITableViewCell.swift | 1 + openHAB/OpenHABDrawerItem.swift | 26 ++- .../OpenHABDrawerTableViewController.swift | 43 ++--- openHAB/OpenHABViewController.swift | 180 +++++++++--------- .../Resources/de.lproj/Localizable.strings | 110 +++++------ openHAB/Resources/en.lproj/InfoPlist.strings | 2 - .../Resources/en.lproj/Localizable.strings | 3 + openHAB/VideoUITableViewCell.swift | 1 + .../Views/ContentView.swift | 4 +- .../Views/Rows/SegmentRow.swift | 14 +- .../Views/Rows/SetpointRow.swift | 2 +- .../Views/Rows/SliderRow.swift | 12 +- .../Views/Rows/SwitchRow.swift | 22 +-- .../ObservableOpenHABWidgetExtension.swift | 2 +- .../openHABWatch Extension/UserData.swift | 84 ++++---- 17 files changed, 262 insertions(+), 249 deletions(-) diff --git a/.swiftformat b/.swiftformat index 4c0ffc009..f5b72bbb3 100644 --- a/.swiftformat +++ b/.swiftformat @@ -6,10 +6,11 @@ # disabled rules --disable specifiers # see https://github.com/nicklockwood/SwiftFormat/issues/364 --disable redundantParens -#--disable wrapMultilineStatementBraces +--disable wrapMultilineStatementBraces # opt-in rules --enable isEmpty +--enable typeSugar # format options --allman false diff --git a/Gemfile.lock b/Gemfile.lock index 2a41ba347..4944156df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,7 +44,7 @@ GEM faraday_middleware (1.0.0) faraday (~> 1.0) fastimage (2.2.0) - fastlane (2.157.1) + fastlane (2.157.2) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) diff --git a/openHAB/NewImageUITableViewCell.swift b/openHAB/NewImageUITableViewCell.swift index c6926c740..415c575f5 100644 --- a/openHAB/NewImageUITableViewCell.swift +++ b/openHAB/NewImageUITableViewCell.swift @@ -52,6 +52,7 @@ class NewImageUITableViewCell: GenericUITableViewCell { } } + @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/openHAB/OpenHABDrawerItem.swift b/openHAB/OpenHABDrawerItem.swift index 2c8f2845b..50632b89b 100644 --- a/openHAB/OpenHABDrawerItem.swift +++ b/openHAB/OpenHABDrawerItem.swift @@ -11,7 +11,27 @@ import Foundation -class OpenHABDrawerItem: NSObject { - var label = "" - var tag = "" +enum OpenHABDrawerItem { + case settings + case notifications + + var localizedString: String { + switch self { + case .settings: + return NSLocalizedString("settings", comment: "") + case .notifications: + return NSLocalizedString("notifications", comment: "") + } + } + + static func openHABDrawerItem(localizedString: String) -> OpenHABDrawerItem { + switch localizedString { + case OpenHABDrawerItem.settings.localizedString: + return OpenHABDrawerItem.settings + case OpenHABDrawerItem.notifications.localizedString: + return OpenHABDrawerItem.notifications + default: + return OpenHABDrawerItem.settings + } + } } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index d23e59ee6..a9718c215 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -175,16 +175,14 @@ class OpenHABDrawerTableViewController: UITableViewController { // Then menu items let drawerItem = drawerItems[indexPath.row - sitemaps.count] - cell.customTextLabel?.text = drawerItem.label + cell.customTextLabel?.text = drawerItem.localizedString if #available(iOS 13, *) { - switch drawerItem.tag { - case "notifications": + switch drawerItem { + case .notifications: cell.customImageView.image = UIImage(systemName: "bell") - case "settings": + case .settings: cell.customImageView.image = UIImage(systemName: "gear") - default: - break } } else { let buttonIcon = DynamicButton(frame: cell.customImageView.bounds) @@ -193,13 +191,11 @@ class OpenHABDrawerTableViewController: UITableViewController { buttonIcon.strokeColor = .black buttonIcon.lineWidth = 1 - switch drawerItem.tag { - case "notifications": + switch drawerItem { + case .notifications: buttonIcon.style = .custom(DynamicButtonStyleBell.self) - case "settings": + case .settings: buttonIcon.style = .custom(DynamicButtonStyleGear.self) - default: - break } cell.customImageView.addSubview(buttonIcon) } @@ -241,14 +237,13 @@ class OpenHABDrawerTableViewController: UITableViewController { // Then menu items let drawerItem = drawerItems[indexPath.row - sitemaps.count] - if drawerItem.tag == "settings" { - dismiss(animated: true) { - self.delegate?.modalDismissed(to: .settings) - } - } else if drawerItem.tag == "notifications" { - dismiss(animated: true) { - self.delegate?.modalDismissed(to: .notifications) - } + switch drawerItem { + case .settings: dismiss(animated: true) { + self.delegate?.modalDismissed(to: .settings) + } + case .notifications: dismiss(animated: true) { + self.delegate?.modalDismissed(to: .notifications) + } } } } @@ -257,16 +252,10 @@ class OpenHABDrawerTableViewController: UITableViewController { // 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 { - let notificationsItem = OpenHABDrawerItem() - notificationsItem.label = "Notifications" - notificationsItem.tag = "notifications" - drawerItems.append(notificationsItem) + drawerItems.append(.notifications) } // Settings always go last - let settingsItem = OpenHABDrawerItem() - settingsItem.label = "Settings" - settingsItem.tag = "settings" - drawerItems.append(settingsItem) + drawerItems.append(.settings) } func loadSettings() { diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index ca8ec66f9..4ebd015a5 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -419,106 +419,106 @@ class OpenHABViewController: UIViewController { currentPageOperation = NetworkConnection.page(pageUrl: pageUrl, longPolling: longPolling, openHABVersion: appData?.openHABVersion ?? 2) { [weak self] response in - guard let self = self else { return } + guard let self = self else { return } - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - let headers = response.response?.allHeaderFields - - NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" - if !NetworkConnection.atmosphereTrackingId.isEmpty { - os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) - } - var openHABSitemapPage: OpenHABSitemapPage? - if let data = response.result.value { - // If we are talking to openHAB 1.X, talk XML - if self.appData?.openHABVersion == 1 { - let str = String(decoding: data, as: UTF8.self) - os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + let headers = response.response?.allHeaderFields - guard let doc = try? XMLDocument(data: data) else { return } - if let rootElement = doc.root, let name = rootElement.tag { - os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) - if name == "page" { - openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" + if !NetworkConnection.atmosphereTrackingId.isEmpty { + os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) + } + var openHABSitemapPage: OpenHABSitemapPage? + if let data = response.result.value { + // If we are talking to openHAB 1.X, talk XML + if self.appData?.openHABVersion == 1 { + let str = String(decoding: data, as: UTF8.self) + os_log("%{PUBLIC}@", log: .remoteAccess, type: .info, str) + + guard let doc = try? XMLDocument(data: data) else { return } + if let rootElement = doc.root, let name = rootElement.tag { + os_log("XML sitemap with root element: %{PUBLIC}@", log: .remoteAccess, type: .info, name) + if name == "page" { + openHABSitemapPage = OpenHABSitemapPage(xml: rootElement) + } + } + } else { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } - } - } else { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) } } - } - self.currentPage = openHABSitemapPage - if self.isFiltering { - self.filterContentForSearchText(self.search.searchBar.text) - } - - self.currentPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - self.widgetTableView.reloadData() - UIApplication.shared.isNetworkActivityIndicatorVisible = false - self.refreshControl?.endRefreshing() - self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] - self.loadPage(true) - 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) + self.currentPage = openHABSitemapPage + if self.isFiltering { + self.filterContentForSearchText(self.search.searchBar.text) + } - NetworkConnection.atmosphereTrackingId = "" - 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 { - os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) - } else { - // Error - DispatchQueue.main.async { - if (error as NSError?)?.code == -1012 { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view - } - } else { - var config = SwiftMessages.Config() - config.duration = .seconds(seconds: 5) - config.presentationStyle = .bottom - - SwiftMessages.show(config: config) { - UIApplication.shared.isNetworkActivityIndicatorVisible = false - let view = MessageView.viewFromNib(layout: .cardView) - // ... configure the view - view.configureTheme(.error) - view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) - view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) - view.buttonTapHandler = { _ in SwiftMessages.hide() } - return view + self.currentPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } + self.widgetTableView.reloadData() + UIApplication.shared.isNetworkActivityIndicatorVisible = false + self.refreshControl?.endRefreshing() + self.navigationItem.title = self.currentPage?.title.components(separatedBy: "[")[0] + self.loadPage(true) + 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 { + os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) + self.loadPage(false) + } else if (error as NSError?)?.code == -999 { + os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) + } else { + // Error + DispatchQueue.main.async { + if (error as NSError?)?.code == -1012 { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: NSLocalizedString("ssl_certificate_error", comment: "")) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } + } else { + var config = SwiftMessages.Config() + config.duration = .seconds(seconds: 5) + config.presentationStyle = .bottom + + SwiftMessages.show(config: config) { + UIApplication.shared.isNetworkActivityIndicatorVisible = false + let view = MessageView.viewFromNib(layout: .cardView) + // ... configure the view + view.configureTheme(.error) + view.configureContent(title: NSLocalizedString("error", comment: ""), body: error.localizedDescription) + view.button?.setTitle(NSLocalizedString("dismiss", comment: ""), for: .normal) + view.buttonTapHandler = { _ in SwiftMessages.hide() } + return view + } } } } } - } } currentPageOperation?.resume() diff --git a/openHAB/Resources/de.lproj/Localizable.strings b/openHAB/Resources/de.lproj/Localizable.strings index f2ccd2222..f7998bfce 100644 --- a/openHAB/Resources/de.lproj/Localizable.strings +++ b/openHAB/Resources/de.lproj/Localizable.strings @@ -1,58 +1,58 @@ -"certficate_exists" = "Certificate already exists in the keychain."; -"message_not_decoded" = "Message could not be decoded"; -"notification" = "Notification"; -"dismiss" = "Dismiss"; -"search_items" = "Search openHAB items"; -"error" = "Error"; -"ssl_certificate_error" = "SSL Certificate Error"; -"empty_sitemap" = "openHAB returned empty sitemap list"; -"connecting" = "Connecting"; -"ssl_certificate_warning" = "SSL Certificate Warning"; -"unable_to_decode_certificate" = "Unable to decode certificate: %@."; -"unable_to_add_certificate" = "Unable to add certificate to the keychain: %@."; -"ssl_certificate_invalid" = "SSL Certificate presented by %1$@ for %2$@ is invalid. Do you want to proceed?"; -"ssl_certificate_no_match" = "SSL Certificate presented by %1$@ for %2$@ doesn't match the record. Do you want to proceed?"; -"abort" = "Abort"; -"once" = "Once"; -"always" = "Always"; -"certificate_import_title" = "Client Certificate Import"; -"certificate_import_text" = "Import client certificate into the keychain?"; -"certificate_import_password" = "Password required for import."; -"okay" = "Okay"; -"cancel" = "Cancel"; -"password" = "Password"; -"copy_label" = "Copy item label"; -"network_not_available" = "Network is not available."; -"connecting_local" = "Connecting to local URL"; -"remote_url_not_configured" = "Remote URL is not configured."; -"connecting_discovered" = "Connecting to discovered URL"; -"running_demo_mode" = "Running in demo mode. Check settings to disable demo mode."; -"discovering_oh" = "Discovering openHAB"; -"settings_not_received" = "Settings not yet received from phone."; -"retry" = "Retry"; -"warning" = "Warning"; +"certficate_exists" = "Zertifikat existiert bereits im Schlüsselbund."; +"message_not_decoded" = "Nachricht konnte nicht dekodiert werden"; +"notification" = "Benachrichtigung"; +"dismiss" = "Verwerfen"; +"search_items" = "Suche openHAB Items"; +"error" = "Fehler"; +"ssl_certificate_error" = "SSL-Zertifikatfehler"; +"empty_sitemap" = "openHAB lieferte eine leere Sitemap-Liste"; +"connecting" = "Verbinden"; +"ssl_certificate_warning" = "SSL-Zertifikatwarnung"; +"unable_to_decode_certificate" = "Zertifikat kann nicht dekodiert werden: %@."; +"unable_to_add_certificate" = "Zertifikat konnte nicht zum Schlüsselbund hinzugefügt werden: %@."; +"ssl_certificate_invalid" = "Das von %1$@ für %2$@ vorgestellte SSL-Zertifikat ist ungültig. Möchten Sie fortfahren?"; +"ssl_certificate_no_match" = "Das von %1$@ für %2$@ vorgestellte SSL-Zertifikat stimmt nicht mit dem Datensatz überein. Möchten Sie fortfahren?"; +"abort" = "Abbrechen"; +"once" = "Einmalig"; +"always" = "Immer"; +"certificate_import_title" = "Clientzertifikatimport"; +"certificate_import_text" = "Clientzertifikat in den Schlüsselbund importieren?"; +"certificate_import_password" = "Passwort wird für den Import benötigt."; +"okay" = "OK"; +"cancel" = "Abbrechen"; +"password" = "Passwort"; +"copy_label" = "Item-Bezeichnung kopieren"; +"network_not_available" = "Netzwerk ist nicht verfügbar."; +"connecting_local" = "Verbinde mit lokaler URL"; +"remote_url_not_configured" = "URL für Fernzugriff ist nicht konfiguriert."; +"connecting_discovered" = "Verbinden mit entdeckter URL"; +"running_demo_mode" = "Läuft im Demomodus. Überprüfen Sie die Einstellungen, um den Demomodus zu deaktivieren."; +"discovering_oh" = "OpenHAB entdecken"; +"settings_not_received" = "Einstellungen noch nicht vom Telefon empfangen."; +"retry" = "Erneut versuchen"; +"warning" = "Warnung"; "version" = "Version"; -"active_url" = "Active URL"; -"local_url" = "Local URL"; -"remote_url" = "Remote URL"; +"active_url" = "Aktive URL"; +"local_url" = "Lokale URL"; +"remote_url" = "URL für Fernzugiff"; "sitemap" = "Sitemap"; -"username" = "Username"; -"sync_prefs" = "Sync preferences"; -"demo_mode" = "Demo mode"; -"always_send_credentials" = "Always send credentials"; -"ignore_ssl_certificates" = "Ignore SSL Certificates"; -"client_certificates" = "Client Certificates"; -"disable_idle_timeout" = "Disable Idle Timeout"; -"real_time_sliders" = "Real-time Sliders"; -"clear_image_cache" = "Clear Image Cache"; -"icon_type" = "Icon Type"; +"username" = "Benutzername"; +"sync_prefs" = "Synchronisationseinstellung"; +"demo_mode" = "Demomodus"; +"always_send_credentials" = "Anmeldedaten immer senden"; +"ignore_ssl_certificates" = "SSL-Zertifikate ignorieren"; +"client_certificates" = "Client-Zertifikate"; +"disable_idle_timeout" = "Bildschirm-Timeout deaktivieren"; +"real_time_sliders" = "Echtzeitschieberegler"; +"clear_image_cache" = "Zwischenspeicher für Bilder leeren"; +"icon_type" = "Icon-Typ"; "info" = "Info"; -"select_sitemap" = "Select Sitemap"; -"crash_reporting" = "Crash Reporting"; -"legal" = "Legal"; -"openhab_connection" = "openHAB Connection"; -"application_settings" = "Application Settings"; -"app_version" = "App Version"; -"oh_version" = "openHAB Version"; -"oh_uuid" = "openHAB UUID"; -"oh_secret" = "openHAB Secret"; +"select_sitemap" = "Sitemap auswählen"; +"crash_reporting" = "Absturzberichte"; +"legal" = "Rechtliches"; +"openhab_connection" = "openHAB Verbindung"; +"application_settings" = "Anwendungseinstellungen"; +"app_version" = "App-Version"; +"oh_version" = "openHAB-Version"; +"oh_uuid" = "openHAB-UUID"; +"oh_secret" = "openHAB-Secret"; diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index 477b28ff8..e69de29bb 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/openHAB/Resources/en.lproj/Localizable.strings b/openHAB/Resources/en.lproj/Localizable.strings index f2ccd2222..9c12ca5c8 100644 --- a/openHAB/Resources/en.lproj/Localizable.strings +++ b/openHAB/Resources/en.lproj/Localizable.strings @@ -56,3 +56,6 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; + diff --git a/openHAB/VideoUITableViewCell.swift b/openHAB/VideoUITableViewCell.swift index 88b0ca9c1..3036e2212 100644 --- a/openHAB/VideoUITableViewCell.swift +++ b/openHAB/VideoUITableViewCell.swift @@ -83,6 +83,7 @@ class VideoUITableViewCell: GenericUITableViewCell { NotificationCenter.default.addObserver(self, selector: #selector(stopPlayback), name: UIApplication.didEnterBackgroundNotification, object: nil) } + @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index 65a64b5ae..45e09c021 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -42,10 +42,10 @@ struct ContentView: View { buttons: [.default(Text(NSLocalizedString("abort", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .deny }, - .default(Text(NSLocalizedString("once", comment: ""))) { + .default(Text(NSLocalizedString("once", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitOnce }, - .default(Text(NSLocalizedString("always", comment: ""))) { + .default(Text(NSLocalizedString("always", comment: ""))) { NetworkConnection.shared.serverCertificateManager.evaluateResult = .permitAlways }]) } diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index fce5d0e74..7a6ae7b55 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -20,14 +20,14 @@ struct SegmentRow: View { @State private var favoriteColor = 0 var body: some View { let valueBinding = Binding(get: { - guard case let .segmented(value) = self.widget.stateEnumBinding else { return 0 } - return value - }, + guard case let .segmented(value) = self.widget.stateEnumBinding else { return 0 } + return value + }, set: { - os_log("Slider new value = %g", log: .default, type: .info, $0) - // self.widget.sendCommand($0) - self.widget.stateEnumBinding = .segmented($0) - }) + os_log("Slider new value = %g", log: .default, type: .info, $0) + // self.widget.sendCommand($0) + self.widget.stateEnumBinding = .segmented($0) + }) return VStack { HStack { diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index d91880368..46c1606b4 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -36,7 +36,7 @@ struct SetpointRow: View { EncircledIconWithAction(systemName: "chevron.down.circle.fill", - action: self.decreaseValue) + action: self.decreaseValue) Spacer() diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index d5c216fc6..6d2ad7c83 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -19,14 +19,14 @@ struct SliderRow: View { var body: some View { let valueBinding = Binding(get: { - self.widget.adjustedValue - }, + self.widget.adjustedValue + }, set: { - os_log("Slider new value = %g", log: .default, type: .info, $0) - self.widget.sendCommand($0.valueText(step: self.widget.step)) + os_log("Slider new value = %g", log: .default, type: .info, $0) + self.widget.sendCommand($0.valueText(step: self.widget.step)) - // self.widget.stateEnumBinding = .slider($0) - }) + // self.widget.stateEnumBinding = .slider($0) + }) return VStack(spacing: 3) { diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index 5ba22b685..ff7273713 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -21,18 +21,18 @@ struct SwitchRow: View { var body: some View { // https://stackoverflow.com/questions/59395501/do-something-when-toggle-state-changes let stateBinding = Binding(get: { - self.widget.stateEnumBinding.boolState - }, + self.widget.stateEnumBinding.boolState + }, set: { - if $0 { - os_log("Switch to ON", log: .viewCycle, type: .info) - self.widget.sendCommand("ON") - } else { - os_log("Switch to OFF", log: .viewCycle, type: .info) - self.widget.sendCommand("OFF") - } - self.widget.stateEnumBinding = .switcher($0) - }) + if $0 { + os_log("Switch to ON", log: .viewCycle, type: .info) + self.widget.sendCommand("ON") + } else { + os_log("Switch to OFF", log: .viewCycle, type: .info) + self.widget.sendCommand("OFF") + } + self.widget.stateEnumBinding = .switcher($0) + }) return Toggle(isOn: stateBinding) { diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift index aa9bc466d..989d610cb 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift @@ -25,7 +25,7 @@ extension ObservableOpenHABWidget { ContentView(viewModel: UserData(url: URL(string: pageUrl)), settings: settings, title: title)) ) { - Image(systemName: "chevron.right") + Image(systemName: "chevron.right") }) } else { diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 11af9b4e3..0b639a67c 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -117,17 +117,17 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: true, openHABVersion: 2) { [weak self] response in - guard self != nil else { return } + guard self != nil else { return } - switch response.result { - case .success: - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - promise.resolve(with: response.result.value ?? Data()) + switch response.result { + case .success: + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + promise.resolve(with: response.result.value ?? Data()) - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - promise.reject(with: error) - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + promise.reject(with: error) + } } currentPageOperation?.resume() @@ -145,44 +145,44 @@ final class UserData: ObservableObject { currentPageOperation = NetworkConnection.page(url: url, longPolling: longPolling, openHABVersion: 2) { [weak self] response in - guard let self = self else { return } - - switch response.result { - case .success: - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - - if let data = response.result.value { - // Newer versions talk JSON! - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - self.openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + guard let self = self else { return } + + switch response.result { + case .success: + os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) + + if let data = response.result.value { + // Newer versions talk JSON! + os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) + do { + // Self-executing closure + // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift + self.openHABSitemapPage = try { + let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + return sitemapPageCodingData.openHABSitemapPage + }() + } catch { + os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) + } } - } - self.openHABSitemapPage?.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } + self.openHABSitemapPage?.sendCommand = { [weak self] item, command in + self?.sendCommand(item, commandToSend: command) + } - self.widgets = self.openHABSitemapPage?.widgets ?? [] + self.widgets = self.openHABSitemapPage?.widgets ?? [] - self.showAlert = self.widgets.isEmpty ? true : false - if refresh { self.loadPage(url: url, - longPolling: true, - refresh: true) } + self.showAlert = self.widgets.isEmpty ? true : false + if refresh { self.loadPage(url: url, + longPolling: true, + refresh: true) } - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - self.errorDescription = error.localizedDescription - self.widgets = [] - self.showAlert = true - } + case let .failure(error): + os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + self.errorDescription = error.localizedDescription + self.widgets = [] + self.showAlert = true + } } currentPageOperation?.resume() } From 4e299ff86aa9783df974586414e72efa119ae767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 22:46:04 +0200 Subject: [PATCH 56/78] Extended translations for openHABDrawerTableViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/Resources/cs.lproj/Localizable.strings | 2 ++ openHAB/Resources/da.lproj/Localizable.strings | 2 ++ openHAB/Resources/de.lproj/Localizable.strings | 2 ++ openHAB/Resources/el.lproj/Localizable.strings | 2 ++ openHAB/Resources/es.lproj/Localizable.strings | 2 ++ openHAB/Resources/fi.lproj/Localizable.strings | 2 ++ openHAB/Resources/fr.lproj/Localizable.strings | 2 ++ openHAB/Resources/hu.lproj/Localizable.strings | 2 ++ openHAB/Resources/it.lproj/Localizable.strings | 2 ++ openHAB/Resources/nb.lproj/Localizable.strings | 2 ++ openHAB/Resources/nl.lproj/Localizable.strings | 2 ++ openHAB/Resources/pl.lproj/Localizable.strings | 2 ++ openHAB/Resources/pt-BR.lproj/Localizable.strings | 2 ++ openHAB/Resources/pt-PT.lproj/Localizable.strings | 2 ++ openHAB/Resources/ro.lproj/Localizable.strings | 2 ++ openHAB/Resources/ru.lproj/Localizable.strings | 2 ++ openHAB/Resources/sr.lproj/Localizable.strings | 2 ++ openHAB/Resources/sv-SE.lproj/Localizable.strings | 2 ++ openHAB/Resources/tr.lproj/Localizable.strings | 2 ++ openHAB/Resources/uk.lproj/Localizable.strings | 2 ++ 20 files changed, 40 insertions(+) diff --git a/openHAB/Resources/cs.lproj/Localizable.strings b/openHAB/Resources/cs.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/cs.lproj/Localizable.strings +++ b/openHAB/Resources/cs.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/da.lproj/Localizable.strings b/openHAB/Resources/da.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/da.lproj/Localizable.strings +++ b/openHAB/Resources/da.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/de.lproj/Localizable.strings b/openHAB/Resources/de.lproj/Localizable.strings index f7998bfce..fb4ab668f 100644 --- a/openHAB/Resources/de.lproj/Localizable.strings +++ b/openHAB/Resources/de.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB-Version"; "oh_uuid" = "openHAB-UUID"; "oh_secret" = "openHAB-Secret"; +"notifications" = "Benachrichtigungen"; +"settings" = "Einstellungen"; diff --git a/openHAB/Resources/el.lproj/Localizable.strings b/openHAB/Resources/el.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/el.lproj/Localizable.strings +++ b/openHAB/Resources/el.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/es.lproj/Localizable.strings b/openHAB/Resources/es.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/es.lproj/Localizable.strings +++ b/openHAB/Resources/es.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/fi.lproj/Localizable.strings b/openHAB/Resources/fi.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/fi.lproj/Localizable.strings +++ b/openHAB/Resources/fi.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/fr.lproj/Localizable.strings b/openHAB/Resources/fr.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/fr.lproj/Localizable.strings +++ b/openHAB/Resources/fr.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/hu.lproj/Localizable.strings b/openHAB/Resources/hu.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/hu.lproj/Localizable.strings +++ b/openHAB/Resources/hu.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/it.lproj/Localizable.strings b/openHAB/Resources/it.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/it.lproj/Localizable.strings +++ b/openHAB/Resources/it.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/nb.lproj/Localizable.strings b/openHAB/Resources/nb.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/nb.lproj/Localizable.strings +++ b/openHAB/Resources/nb.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/nl.lproj/Localizable.strings b/openHAB/Resources/nl.lproj/Localizable.strings index d45bd91ca..b847d9a30 100644 --- a/openHAB/Resources/nl.lproj/Localizable.strings +++ b/openHAB/Resources/nl.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Versie"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB geheim"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/pl.lproj/Localizable.strings b/openHAB/Resources/pl.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/pl.lproj/Localizable.strings +++ b/openHAB/Resources/pl.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/pt-BR.lproj/Localizable.strings b/openHAB/Resources/pt-BR.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/pt-BR.lproj/Localizable.strings +++ b/openHAB/Resources/pt-BR.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/pt-PT.lproj/Localizable.strings b/openHAB/Resources/pt-PT.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/pt-PT.lproj/Localizable.strings +++ b/openHAB/Resources/pt-PT.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/ro.lproj/Localizable.strings b/openHAB/Resources/ro.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/ro.lproj/Localizable.strings +++ b/openHAB/Resources/ro.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/ru.lproj/Localizable.strings b/openHAB/Resources/ru.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/ru.lproj/Localizable.strings +++ b/openHAB/Resources/ru.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/sr.lproj/Localizable.strings b/openHAB/Resources/sr.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/sr.lproj/Localizable.strings +++ b/openHAB/Resources/sr.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/sv-SE.lproj/Localizable.strings b/openHAB/Resources/sv-SE.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/sv-SE.lproj/Localizable.strings +++ b/openHAB/Resources/sv-SE.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/tr.lproj/Localizable.strings b/openHAB/Resources/tr.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/tr.lproj/Localizable.strings +++ b/openHAB/Resources/tr.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; diff --git a/openHAB/Resources/uk.lproj/Localizable.strings b/openHAB/Resources/uk.lproj/Localizable.strings index f2ccd2222..f60f6d015 100644 --- a/openHAB/Resources/uk.lproj/Localizable.strings +++ b/openHAB/Resources/uk.lproj/Localizable.strings @@ -56,3 +56,5 @@ "oh_version" = "openHAB Version"; "oh_uuid" = "openHAB UUID"; "oh_secret" = "openHAB Secret"; +"notifications" = "Notifications"; +"settings" = "Settings"; From b3e8f6fd7a8b036bb80e8bc73c1a6708bad63f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Fri, 28 Aug 2020 22:52:30 +0200 Subject: [PATCH 57/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 2574b2502..9dd93f572 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -2011,7 +2011,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2055,7 +2055,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2067,7 +2067,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2096,7 +2096,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2115,7 +2115,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2144,7 +2144,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2162,7 +2162,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2192,7 +2192,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2210,7 +2210,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2242,7 +2242,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2259,7 +2259,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2290,14 +2290,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2329,14 +2329,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2365,7 +2365,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2377,7 +2377,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2407,7 +2407,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2419,7 +2419,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2449,7 +2449,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2461,7 +2461,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2494,7 +2494,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2506,7 +2506,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2647,7 +2647,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2664,7 +2664,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2694,7 +2694,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410452; + CURRENT_PROJECT_VERSION = 1580410453; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2711,7 +2711,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.3; + MARKETING_VERSION = 2.4.4; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From 1140537679552abbc740f79acaa77fe9bca87b8e Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 30 Aug 2020 09:00:36 +0200 Subject: [PATCH 58/78] respond to authenticatin challenge --- openHAB/WebUITableViewCell.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openHAB/WebUITableViewCell.swift b/openHAB/WebUITableViewCell.swift index 66d0e66a9..67efca0b5 100644 --- a/openHAB/WebUITableViewCell.swift +++ b/openHAB/WebUITableViewCell.swift @@ -108,4 +108,9 @@ extension WebUITableViewCell: WKNavigationDelegate { os_log("webview failed with error: %{PUBLIC}s", log: .urlComposition, type: .debug, error.localizedDescription) url = nil } + + func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + let (disposition, credential) = onReceiveSessionChallenge(URLSession(configuration: .default), challenge) + completionHandler(disposition, credential) + } } From 64c1c6a75d8f468e389ba416de47f564449f018e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Mon, 31 Aug 2020 17:35:45 +0200 Subject: [PATCH 59/78] Localization for OpenHABClientCertificatesViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- openHAB/OpenHABClientCertificatesViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/openHAB/OpenHABClientCertificatesViewController.swift b/openHAB/OpenHABClientCertificatesViewController.swift index a23d0951c..c22a036d8 100644 --- a/openHAB/OpenHABClientCertificatesViewController.swift +++ b/openHAB/OpenHABClientCertificatesViewController.swift @@ -24,6 +24,7 @@ class OpenHABClientCertificatesViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() + navigationItem.title = NSLocalizedString("client_certificates", comment: "") os_log("OpenHABClientCertificatesViewController viewDidLoad", log: .default, type: .info) tableView.tableFooterView = UIView() From bebb09ffb02c527042e58888c34ddf431b866156 Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 6 Sep 2020 11:03:55 +0200 Subject: [PATCH 60/78] update github workflow --- .github/workflows/publish.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 560e54989..8bc45a0c1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -46,7 +46,6 @@ jobs: with: ssh-private-key: | ${{ secrets.MATCH_GIT_PRIVATE_KEY }} - ${{ secrets.GIT_PRIVATE_KEY }} - name: fastlane iOS beta env: From 40f29f039affcdbf3d33da36fdfd1ca3f4aadda6 Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 9 Sep 2020 16:45:13 +0200 Subject: [PATCH 61/78] update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 18 +++++++--- .github/ISSUE_TEMPLATE/config.yml | 8 +++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ----------- .github/ISSUE_TEMPLATE/regression.md | 42 +++++++++++++++++++++++ 4 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/regression.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3318138c7..2ffc982d8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,12 +1,17 @@ --- -name: Bug report -about: Create a report to help us improve +name: 🐛 Bug Report +about: If something isn't working as expected title: '' labels: '' assignees: '' - --- +**New bug checklist** + +- [ ] I updated the iOS openHAB app to the latest [TestFlight](https://testflight.apple.com/join/563WBakc) version. +- [ ] I read the [Contribution Guidelines](https://github.com/openhab/openhab-ios/blob/develop/CONTRIBUTING.md) +- [ ] I searched for [existing GitHub issues](https://github.com/openhab/openhab-ios/issues) + **Describe the bug** A clear and concise description of what the bug is. @@ -24,10 +29,13 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **App (please complete the following information):** - - Version [e.g. 2.1.0(12)] + - Version [e.g. `2.1.0 (12)`] **Smartphone (please complete the following information):** - - Device: [e.g. iPhoneXR] + - Device: [e.g. `iPhoneXR`] + +**openHAB (please complete the following information):** +- Version [e.g. `2.5.8`] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..f0be00f8f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: 🚀 Feature Request + url: https://github.com/openhab/openhab-ios/discussions/new?category_id=27710982 + about: Share ideas for new features + - name: ❓ Ask a Question + url: https://github.com/openhab/openhab-ios/discussions/new?category_id=27710981 + about: Ask the community for help diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d6..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/regression.md b/.github/ISSUE_TEMPLATE/regression.md new file mode 100644 index 000000000..d86a8b40c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/regression.md @@ -0,0 +1,42 @@ +--- +name: 🐛 Bug Report +about: If a recent release broke a feature +title: '' +labels: '' +assignees: '' +--- + +**New regression checklist** + +- [ ] I updated the iOS openHAB app to the latest [TestFlight](https://testflight.apple.com/join/563WBakc) version. +- [ ] I read the [Contribution Guidelines](https://github.com/openhab/openhab-ios/blob/develop/CONTRIBUTING.md) +- [ ] I searched for [existing GitHub issues](https://github.com/openhab/openhab-ios/issues) + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**App (please complete the following information):** + - Breaking version: [e.g. `2.1.0 (12)`] + - Last working version: [e.g. `2.2.0 (13)`] + +**Smartphone (please complete the following information):** + - Device: [e.g. `iPhoneXR`] + +**openHAB (please complete the following information):** +- Version [e.g. `2.5.8`] + +**Additional context** +Add any other context about the problem here. From f4a8a5cd2436f20b7e5868f5ba23834ce2f9d34b Mon Sep 17 00:00:00 2001 From: weak Date: Wed, 9 Sep 2020 16:49:14 +0200 Subject: [PATCH 62/78] update issue templates --- .github/ISSUE_TEMPLATE/regression.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/regression.md b/.github/ISSUE_TEMPLATE/regression.md index d86a8b40c..275ba5b33 100644 --- a/.github/ISSUE_TEMPLATE/regression.md +++ b/.github/ISSUE_TEMPLATE/regression.md @@ -1,5 +1,5 @@ --- -name: 🐛 Bug Report +name: 😱 Regression about: If a recent release broke a feature title: '' labels: '' From a4b56a40f7a8b009f0c06fc090e846e29214152e Mon Sep 17 00:00:00 2001 From: weak Date: Fri, 18 Sep 2020 09:22:34 +0200 Subject: [PATCH 63/78] add post_install and post_integrate hooks to work around Xcode 12 warnings --- Podfile | 25 +++++++++++++++++++++++++ Podfile.lock | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Podfile b/Podfile index da4ac61f8..b452d5a3b 100644 --- a/Podfile +++ b/Podfile @@ -78,4 +78,29 @@ post_install do |installer| end end end + + # workaround for Xcode 12 warnings + installer.generated_projects.each do |project| + project.root_object.attributes['LastUpgradeCheck'] = 1200 + project.build_configurations.each do |config| + if config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8.0' || config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0' + end + end + + user_data_dir = Xcodeproj::XCScheme.user_data_dir(project.path) + project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET' + scheme_filename = "#{user_data_dir}/#{target}.xcscheme" + `sed -i '' 's/LastUpgradeVersion = \"1100\"/LastUpgradeVersion = \"1200\"/' "#{scheme_filename}"` + end + end + end +end + +post_integrate do |installer| + pbxproj_file = "#{installer.pods_project.path}/project.pbxproj" + puts pbxproj_file + `sed -i '' 's/LastUpgradeCheck = 1100/LastUpgradeCheck = 1200/' "#{pbxproj_file}"` end diff --git a/Podfile.lock b/Podfile.lock index f527db166..e46f433cc 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -166,6 +166,6 @@ SPEC CHECKSUMS: SwiftLint: bbfed21bf4451dcbd0f5cdbee44a18e06cf91b12 SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 -PODFILE CHECKSUM: 7e3ab1cfad25c0c0ad6f55cd58134ce3b910ec2e +PODFILE CHECKSUM: 2a92ef8ab608fd27b9db147f23ffb78db541f5a7 -COCOAPODS: 1.10.0.beta.2 +COCOAPODS: 1.10.0.rc.1 From e58783abfcf3739a9366bb9f698f59027232c46f Mon Sep 17 00:00:00 2001 From: weak Date: Fri, 18 Sep 2020 09:26:55 +0200 Subject: [PATCH 64/78] update project settings for Xcode 12 --- openHAB.xcodeproj/project.pbxproj | 4 ++- .../xcschemes/openHABTestsSwift.xcscheme | 9 +++++++ .../openHABWatch (Notification).xcscheme | 25 ++++++++++++++----- .../xcschemes/openHABWatch.xcscheme | 25 ++++++++++++++----- .../openHABWatchSwift (Complication).xcscheme | 25 ++++++++++++++----- 5 files changed, 69 insertions(+), 19 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 9dd93f572..0240f76ed 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1317,7 +1317,7 @@ attributes = { CLASSPREFIX = OpenHAB; LastSwiftUpdateCheck = 1100; - LastUpgradeCheck = 1120; + LastUpgradeCheck = 1200; ORGANIZATIONNAME = "openHAB e.V."; TargetAttributes = { 933D7F0322E7015000621A03 = { @@ -2545,6 +2545,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = NO; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -2604,6 +2605,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = NO; CLANG_WARN_SUSPICIOUS_MOVE = YES; diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme index 5825c9ceb..f8a058ccf 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABTestsSwift.xcscheme @@ -57,6 +57,15 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> + + + + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme index b8cca27d4..7ba8fde1a 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme @@ -56,8 +56,10 @@ allowLocationSimulation = "YES" launchAutomaticallySubstyle = "8" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme index 449e47642..373069cd5 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme @@ -55,8 +55,10 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme index 3bd32af54..85f61fb05 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme @@ -55,8 +55,10 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "32"> - + - + - + - + + + + + From fa6e7844649463437f47968cfa5164987b223355 Mon Sep 17 00:00:00 2001 From: weak Date: Fri, 18 Sep 2020 09:27:17 +0200 Subject: [PATCH 65/78] bump swift version --- .swiftformat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.swiftformat b/.swiftformat index f5b72bbb3..1e656b90a 100644 --- a/.swiftformat +++ b/.swiftformat @@ -1,5 +1,5 @@ # file options ---swiftversion 5.2 +--swiftversion 5.3 --exclude Pods --symlinks ignore From c9feb8cf293d473ea9fc2b8a75cbec36f3678fec Mon Sep 17 00:00:00 2001 From: weak Date: Fri, 18 Sep 2020 09:41:37 +0200 Subject: [PATCH 66/78] fix post_integrate hook --- Podfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Podfile b/Podfile index b452d5a3b..3a39ffe6b 100644 --- a/Podfile +++ b/Podfile @@ -100,7 +100,8 @@ post_install do |installer| end post_integrate do |installer| - pbxproj_file = "#{installer.pods_project.path}/project.pbxproj" - puts pbxproj_file - `sed -i '' 's/LastUpgradeCheck = 1100/LastUpgradeCheck = 1200/' "#{pbxproj_file}"` + if defined?(installer.pods_project.path) + pbxproj_file = "#{installer.pods_project.path}/project.pbxproj" + `sed -i '' 's/LastUpgradeCheck = 1100/LastUpgradeCheck = 1200/' "#{pbxproj_file}"` + end end From ee0ab6ea679e09ce3da34e142bbeb98be4071ee7 Mon Sep 17 00:00:00 2001 From: weak Date: Fri, 18 Sep 2020 10:10:04 +0200 Subject: [PATCH 67/78] add NSLocalNetworkUsageDescription --- openHAB/Resources/en.lproj/InfoPlist.strings | 1 + openHAB/openHAB-Info.plist | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/openHAB/Resources/en.lproj/InfoPlist.strings b/openHAB/Resources/en.lproj/InfoPlist.strings index e69de29bb..d075bedf2 100644 --- a/openHAB/Resources/en.lproj/InfoPlist.strings +++ b/openHAB/Resources/en.lproj/InfoPlist.strings @@ -0,0 +1 @@ +"NSLocalNetworkUsageDescription" = "openHAB needs access to your local network to connect with the openHAB server."; diff --git a/openHAB/openHAB-Info.plist b/openHAB/openHAB-Info.plist index e38b45929..5bab6978e 100644 --- a/openHAB/openHAB-Info.plist +++ b/openHAB/openHAB-Info.plist @@ -112,5 +112,12 @@ firebase_crashlytics_collection_enabled + NSLocalNetworkUsageDescription + openHAB needs access to your local network to connect with the openHAB server. + NSBonjourServices + + _http._tcp + _openhab-server-ssl._tcp + From 088aff5911ae1701f2d840474229c3194546f5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Thu, 24 Sep 2020 21:38:36 +0200 Subject: [PATCH 68/78] Update Kingfisher to 5.15.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Podfile | 2 -- Podfile.lock | 18 +++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Podfile b/Podfile index 3a39ffe6b..053f2d25c 100644 --- a/Podfile +++ b/Podfile @@ -26,8 +26,6 @@ target 'openHAB' do pod 'DynamicButton', '~> 6.2' pod 'SideMenu', '~> 6.4' pod 'Kingfisher', '~> 5.0' - #pod "Macaw", "0.9.6" - #pod 'SwiftSVG', '~> 2.0' target 'openHABTestsSwift' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index e46f433cc..542cc51a2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -67,10 +67,10 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.1): - GoogleUtilities/Logger - - Kingfisher (5.14.1): - - Kingfisher/Core (= 5.14.1) - - Kingfisher/Core (5.14.1) - - Kingfisher/SwiftUI (5.14.1): + - Kingfisher (5.15.4): + - Kingfisher/Core (= 5.15.4) + - Kingfisher/Core (5.15.4) + - Kingfisher/SwiftUI (5.15.4): - Kingfisher/Core - nanopb (1.30905.0): - nanopb/decode (= 1.30905.0) @@ -137,16 +137,16 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: SVGKit: - :commit: 9240977515c04053f8c96c9dfdb764dc7b98b9ba + :commit: 58543f3714b34ea66cfe58636d86dcbec3514ccf :git: https://github.com/SVGKit/SVGKit.git SPEC CHECKSUMS: Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94 - Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df + Crashlytics: 9220f5bc89e7a618df411b4f639389dbfb0e03d2 DeviceKit: d081659419cce07c0b5239dbc9fb39ed7413c7fe DynamicButton: 95f30460793bd3510a5c213ac1b810a5e3d54b6a - Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 + Fabric: ea977e3cd9c20425516d3dafd3bf8c941c51223f Firebase: 57957c8d6eb3d8b80a560b1dc58be24724b89ff2 FirebaseAnalytics: aa522dce9fd93002ba1554467d23ce7092323000 FirebaseCore: 7930a1946517d94256d857f97371ed993b55f7bd @@ -157,7 +157,7 @@ SPEC CHECKSUMS: GoogleAppMeasurement: 345d365fd105e6682bf5084783a5352a3db26820 GoogleDataTransport: af0c79193dc59acd37630b4833d0dc6912ae6bd5 GoogleUtilities: e121a3867449ce16b0e35ddf1797ea7a389ffdf2 - Kingfisher: 8050bc6f7f68cbf3908bd04df7ccbac188f6d6d6 + Kingfisher: 657dc1077e5bbbfff864194c79f29e35b722d062 nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 @@ -166,6 +166,6 @@ SPEC CHECKSUMS: SwiftLint: bbfed21bf4451dcbd0f5cdbee44a18e06cf91b12 SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 -PODFILE CHECKSUM: 2a92ef8ab608fd27b9db147f23ffb78db541f5a7 +PODFILE CHECKSUM: a3b3c052c977017e5aa90886724865a86c41afbe COCOAPODS: 1.10.0.rc.1 From d98a6415b1bfb401b067d933242c49a86bd15b41 Mon Sep 17 00:00:00 2001 From: weak Date: Sat, 3 Oct 2020 08:26:26 +0200 Subject: [PATCH 69/78] update external dependencies, migrate to FirebaseCrashlytics, remove FirebaseAnalytics --- Podfile | 6 +- Podfile.lock | 155 +++++++----------- openHAB.xcodeproj/project.pbxproj | 2 +- .../openHABWatch (Notification).xcscheme | 25 +-- .../xcschemes/openHABWatch.xcscheme | 25 +-- .../openHABWatchSwift (Complication).xcscheme | 25 +-- openHAB/legal.rtf | 17 +- 7 files changed, 88 insertions(+), 167 deletions(-) diff --git a/Podfile b/Podfile index 053f2d25c..4e0a0433f 100644 --- a/Podfile +++ b/Podfile @@ -16,9 +16,7 @@ target 'openHAB' do pod 'SwiftLint' pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '3.x' - pod 'Fabric', '~> 1.7' - pod 'Crashlytics', '~> 3.9' - pod 'Firebase/Analytics' + pod 'Firebase/Crashlytics' pod 'SwiftMessages' pod 'FlexColorPicker' @@ -55,7 +53,7 @@ target 'openHABWatch Extension' do inherit! :search_paths shared_pods pod 'Kingfisher/SwiftUI', '~> 5.0' - pod 'DeviceKit', '~> 3.0' + pod 'DeviceKit', '~> 4.0' end # Note: `pod install --clean-install` must be used if the post_install hook is changed diff --git a/Podfile.lock b/Podfile.lock index 542cc51a2..8f0c94c6a 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,99 +1,70 @@ PODS: - Alamofire (4.9.1) - - CocoaLumberjack (3.6.2): - - CocoaLumberjack/Core (= 3.6.2) - - CocoaLumberjack/Core (3.6.2) - - Crashlytics (3.14.0): - - Fabric (~> 1.10.2) - - DeviceKit (3.2.0) + - CocoaLumberjack (3.7.0): + - CocoaLumberjack/Core (= 3.7.0) + - CocoaLumberjack/Core (3.7.0) + - DeviceKit (4.1.0) - DynamicButton (6.2.1) - - Fabric (1.10.2) - - Firebase/Analytics (6.29.0): - - Firebase/Core - - Firebase/Core (6.29.0): + - Firebase/CoreOnly (6.33.0): + - FirebaseCore (= 6.10.3) + - Firebase/Crashlytics (6.33.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.7.0) - - Firebase/CoreOnly (6.29.0): - - FirebaseCore (= 6.9.2) - - FirebaseAnalytics (6.7.0): - - FirebaseCore (~> 6.8) - - FirebaseInstallations (~> 1.4) - - GoogleAppMeasurement (= 6.7.0) - - GoogleUtilities/AppDelegateSwizzler (~> 6.7) - - GoogleUtilities/MethodSwizzler (~> 6.7) - - GoogleUtilities/Network (~> 6.7) - - "GoogleUtilities/NSData+zlib (~> 6.7)" - - nanopb (~> 1.30905.0) - - FirebaseCore (6.9.2): - - FirebaseCoreDiagnostics (~> 1.3) + - FirebaseCrashlytics (~> 4.6.1) + - FirebaseCore (6.10.3): + - FirebaseCoreDiagnostics (~> 1.6) - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Logger (~> 6.7) - - FirebaseCoreDiagnostics (1.5.0): - - GoogleDataTransport (~> 7.0) + - FirebaseCoreDiagnostics (1.7.0): + - GoogleDataTransport (~> 7.4) - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Logger (~> 6.7) - - nanopb (~> 1.30905.0) - - FirebaseInstallations (1.5.0): - - FirebaseCore (~> 6.8) + - nanopb (~> 1.30906.0) + - FirebaseCrashlytics (4.6.1): + - FirebaseCore (~> 6.10) + - FirebaseInstallations (~> 1.6) + - GoogleDataTransport (~> 7.2) + - nanopb (~> 1.30906.0) + - PromisesObjC (~> 1.2) + - FirebaseInstallations (1.7.0): + - FirebaseCore (~> 6.10) - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/UserDefaults (~> 6.7) - PromisesObjC (~> 1.2) - FlexColorPicker (1.4.2) - Fuzi (3.1.2) - - GoogleAppMeasurement (6.7.0): - - GoogleUtilities/AppDelegateSwizzler (~> 6.7) - - GoogleUtilities/MethodSwizzler (~> 6.7) - - GoogleUtilities/Network (~> 6.7) - - "GoogleUtilities/NSData+zlib (~> 6.7)" - - nanopb (~> 1.30905.0) - - GoogleDataTransport (7.1.0): - - nanopb (~> 1.30905.0) - - GoogleUtilities/AppDelegateSwizzler (6.7.1): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (6.7.1): + - GoogleDataTransport (7.4.0): + - nanopb (~> 1.30906.0) + - GoogleUtilities/Environment (6.7.2): - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.7.1): + - GoogleUtilities/Logger (6.7.2): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.7.1): - - GoogleUtilities/Logger - - GoogleUtilities/Network (6.7.1): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.7.1)" - - GoogleUtilities/Reachability (6.7.1): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.7.1): + - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger - - Kingfisher (5.15.4): - - Kingfisher/Core (= 5.15.4) - - Kingfisher/Core (5.15.4) - - Kingfisher/SwiftUI (5.15.4): + - Kingfisher (5.15.5): + - Kingfisher/Core (= 5.15.5) + - Kingfisher/Core (5.15.5) + - Kingfisher/SwiftUI (5.15.5): - Kingfisher/Core - - nanopb (1.30905.0): - - nanopb/decode (= 1.30905.0) - - nanopb/encode (= 1.30905.0) - - nanopb/decode (1.30905.0) - - nanopb/encode (1.30905.0) - - PromisesObjC (1.2.9) + - nanopb (1.30906.0): + - nanopb/decode (= 1.30906.0) + - nanopb/encode (= 1.30906.0) + - nanopb/decode (1.30906.0) + - nanopb/encode (1.30906.0) + - PromisesObjC (1.2.10) - SideMenu (6.4.9) - SVGKit (2.1.0): - CocoaLumberjack (~> 3.0) - - SwiftFormat/CLI (0.46.0) - - SwiftLint (0.40.1) - - SwiftMessages (8.0.0): - - SwiftMessages/App (= 8.0.0) - - SwiftMessages/App (8.0.0) + - SwiftFormat/CLI (0.46.3) + - SwiftLint (0.40.3) + - SwiftMessages (8.0.2): + - SwiftMessages/App (= 8.0.2) + - SwiftMessages/App (8.0.2) DEPENDENCIES: - Alamofire (~> 4.0) - - Crashlytics (~> 3.9) - - DeviceKit (~> 3.0) + - DeviceKit (~> 4.0) - DynamicButton (~> 6.2) - - Fabric (~> 1.7) - - Firebase/Analytics + - Firebase/Crashlytics - FlexColorPicker - Fuzi (~> 3.1) - Kingfisher (~> 5.0) @@ -108,18 +79,15 @@ SPEC REPOS: trunk: - Alamofire - CocoaLumberjack - - Crashlytics - DeviceKit - DynamicButton - - Fabric - Firebase - - FirebaseAnalytics - FirebaseCore - FirebaseCoreDiagnostics + - FirebaseCrashlytics - FirebaseInstallations - FlexColorPicker - Fuzi - - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities - Kingfisher @@ -142,30 +110,27 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18 - CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94 - Crashlytics: 9220f5bc89e7a618df411b4f639389dbfb0e03d2 - DeviceKit: d081659419cce07c0b5239dbc9fb39ed7413c7fe + CocoaLumberjack: e8955b9d337ac307103b0a34fd141c32f27e53c5 + DeviceKit: aaa4743a15ef1e2021fe654dffa32a3ed15672aa DynamicButton: 95f30460793bd3510a5c213ac1b810a5e3d54b6a - Fabric: ea977e3cd9c20425516d3dafd3bf8c941c51223f - Firebase: 57957c8d6eb3d8b80a560b1dc58be24724b89ff2 - FirebaseAnalytics: aa522dce9fd93002ba1554467d23ce7092323000 - FirebaseCore: 7930a1946517d94256d857f97371ed993b55f7bd - FirebaseCoreDiagnostics: 7535fe695737f8c5b350584292a70b7f8ff0357b - FirebaseInstallations: 3c520c951305cbf9ca54eb891ff9e6d1fd384881 + Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 + FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd + FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 + FirebaseCrashlytics: 5777d3462fb8c3ab9e80a2473bd7d667a2e8411c + FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 FlexColorPicker: d7ed5cfd8ceb936f2930e4e30629f9448967a5f8 Fuzi: dba7215e52fb39dd7b1a62f69ede1e30edff0ae1 - GoogleAppMeasurement: 345d365fd105e6682bf5084783a5352a3db26820 - GoogleDataTransport: af0c79193dc59acd37630b4833d0dc6912ae6bd5 - GoogleUtilities: e121a3867449ce16b0e35ddf1797ea7a389ffdf2 - Kingfisher: 657dc1077e5bbbfff864194c79f29e35b722d062 - nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 - PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 + GoogleDataTransport: b7f406340a291370045a270c599e53c6fa6ec20f + GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + Kingfisher: e3ec347a5ab8817b7585ef46923a2d2b9a7d8fbe + nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc + PromisesObjC: b14b1c6b68e306650688599de8a45e49fae81151 SideMenu: 8ef57a3cfc024a2d3fc1c036c7fe98537baec9e0 SVGKit: 132b010efbf57ec345309fe4a7f627c0a40c5d63 - SwiftFormat: 4da2465002f4c5514327a4376d7cbb475a6358c8 - SwiftLint: bbfed21bf4451dcbd0f5cdbee44a18e06cf91b12 - SwiftMessages: 29e7975b1173fd4e8357600c6518b5a59bc607d6 + SwiftFormat: b639417da9e024b9e782f917bc9a080cf75bcb37 + SwiftLint: dfd554ff0dff17288ee574814ccdd5cea85d76f7 + SwiftMessages: 633304165351b8e3dcbb81a71f8efcd86f9c1669 -PODFILE CHECKSUM: a3b3c052c977017e5aa90886724865a86c41afbe +PODFILE CHECKSUM: 8b24d9f55d88a62f1c5b322c170fef2e39a3ecfe COCOAPODS: 1.10.0.rc.1 diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 0240f76ed..0737ffad1 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -1532,7 +1532,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; + shellScript = "${PODS_ROOT}/FirebaseCrashlytics/run\n"; }; 6CFD91FCB0795A11D94FFA99 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme index 7ba8fde1a..b8cca27d4 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme @@ -56,10 +56,8 @@ allowLocationSimulation = "YES" launchAutomaticallySubstyle = "8" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme index 373069cd5..449e47642 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme @@ -55,10 +55,8 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - - - - - + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme index 85f61fb05..3bd32af54 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme @@ -55,10 +55,8 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "32"> - + - + - + - - - - - + diff --git a/openHAB/legal.rtf b/openHAB/legal.rtf index 9c3516c18..bd4ec163b 100644 --- a/openHAB/legal.rtf +++ b/openHAB/legal.rtf @@ -1,8 +1,8 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 -{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} +{\rtf1\ansi\ansicpg1252\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} -\paperw12240\paperh15840\margl1440\margr1440\vieww17380\viewh8400\viewkind0 +\margl1440\margr1440\vieww17380\viewh8400\viewkind0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f0\fs24 \cf0 Copyright (c) 2010-2019, Contributors to the openHAB project\ @@ -386,15 +386,12 @@ Redistribution and use in source and binary forms, with or without modification, 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ 3 Neither the name of Deusty nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Deusty, LLC.\ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \'93AS IS\'94 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ -Crashlytics\ -Fabric: Copyright 2017 Google, Inc. All Rights Reserved. Use of this software is subject to the terms and conditions of the Fabric Software and Services Agreement located at https://fabric.io/terms. Crashlytics Kit: Copyright 2017 Crashlytics, Inc. All Rights Reserved. Use of this software is subject to the terms and conditions of the Crashlytics Terms of Service located at http://try.crashlytics.com/terms/terms-of-service.pdf and the Crashlytics Privacy Policy located at http://try.crashlytics.com/terms/privacy-policy.pdf. OSS: http://get.fabric.io/terms/opensource.txt\ -Fabric\ -Fabric: Copyright 2018 Google, Inc. All Rights Reserved. Use of this software is subject to the terms and conditions of the Fabric Software and Services Agreement located at https://fabric.io/terms. OSS: http://get.fabric.io/terms/opensource.txt\ Firebase\ -Copyright 2019 Google\ -FirebaseAnalytics\ -Copyright 2019 Google\ +Copyright 2020 Google\ FirebaseCore\ +Copyright 2020 Google\ +FirebaseCrashlytics\ +Copyright 2020 Google\ Apache License\ Version 2.0, January 2004\ http://www.apache.org/licenses/\ From 7bc8ba0fa3f2cdd8c4a20db1ff3ded9a2433d3b3 Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 4 Oct 2020 13:23:46 +0200 Subject: [PATCH 70/78] minor refactoring --- openHAB/OpenHABViewController.swift | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/openHAB/OpenHABViewController.swift b/openHAB/OpenHABViewController.swift index 4ebd015a5..650ef8d8d 100644 --- a/openHAB/OpenHABViewController.swift +++ b/openHAB/OpenHABViewController.swift @@ -62,32 +62,33 @@ private let openHABViewControllerMapViewCellReuseIdentifier = "OpenHABViewContro private let openHABViewControllerImageViewCellReuseIdentifier = "OpenHABViewControllerImageViewCellReuseIdentifier" class OpenHABViewController: UIViewController { - var tracker: OpenHABTracker? - var hamburgerButton: DynamicButton! + var pageUrl = "" + + private var tracker: OpenHABTracker? + private var hamburgerButton: DynamicButton! private var selectedWidgetRow: Int = 0 private var currentPageOperation: Alamofire.Request? private var commandOperation: Alamofire.Request? - var pageUrl = "" - var openHABRootUrl = "" - var openHABUsername = "" - var openHABPassword = "" - var openHABAlwaysSendCreds = false - var defaultSitemap = "" - var idleOff = false - var sitemaps: [OpenHABSitemap] = [] - var currentPage: OpenHABSitemapPage? - var selectionPicker: UIPickerView? - var pageNetworkStatus: NetworkReachabilityManager.NetworkReachabilityStatus? - var pageNetworkStatusAvailable = false - var toggle: Int = 0 - var deviceToken = "" - var deviceId = "" - var deviceName = "" - var refreshControl: UIRefreshControl? - var iconType: IconType = .png - let search = UISearchController(searchResultsController: nil) - var filteredPage: OpenHABSitemapPage? - var serverProperties: OpenHABServerProperties? + private var iconType: IconType = .png + private var openHABRootUrl = "" + private var openHABUsername = "" + private var openHABPassword = "" + private var openHABAlwaysSendCreds = false + private var defaultSitemap = "" + private var idleOff = false + private var sitemaps: [OpenHABSitemap] = [] + private var currentPage: OpenHABSitemapPage? + private var selectionPicker: UIPickerView? + private var pageNetworkStatus: NetworkReachabilityManager.NetworkReachabilityStatus? + private var pageNetworkStatusAvailable = false + private var toggle: Int = 0 + private var deviceToken = "" + private var deviceId = "" + private var deviceName = "" + private var refreshControl: UIRefreshControl? + private var filteredPage: OpenHABSitemapPage? + private var serverProperties: OpenHABServerProperties? + private let search = UISearchController(searchResultsController: nil) var relevantPage: OpenHABSitemapPage? { if isFiltering { From dc970b4bee02bc25f4061bcb2363855403ee283e Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 4 Oct 2020 13:23:56 +0200 Subject: [PATCH 71/78] fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ceed5d4d1..b38b5ec30 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Bountysource + Bountysource
Logo
@@ -12,7 +12,7 @@ This app is a native client for openHAB which allows easy access to your sitemap Download on the App Store -Beta releases are available on [Test Flight](https://testflight.apple.com/join/563WBakc). +Beta releases are available on [TestFlight](https://testflight.apple.com/join/563WBakc). ## Features * Control your openHAB server and [openHAB Cloud instance](https://github.com/openhab/openhab-cloud) From 127bda7c5bf9a7e62c3992a3244b2f2fa6135ce5 Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 4 Oct 2020 14:15:40 +0200 Subject: [PATCH 72/78] update Podfile and SVGKit --- Podfile | 6 +++--- Podfile.lock | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Podfile b/Podfile index 4e0a0433f..ec5af83a2 100644 --- a/Podfile +++ b/Podfile @@ -1,7 +1,7 @@ -install! 'cocoapods', :generate_multiple_pod_projects => true, :incremental_installation => true +source 'https://github.com/CocoaPods/Specs.git' -#platform :ios, '11.0' -# +install! 'cocoapods', :generate_multiple_pod_projects => true, :incremental_installation => true +inhibit_all_warnings! use_frameworks! def shared_pods diff --git a/Podfile.lock b/Podfile.lock index 8f0c94c6a..97bb4b1b7 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -76,9 +76,10 @@ DEPENDENCIES: - SwiftMessages SPEC REPOS: + https://github.com/CocoaPods/Specs.git: + - CocoaLumberjack trunk: - Alamofire - - CocoaLumberjack - DeviceKit - DynamicButton - Firebase @@ -105,7 +106,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: SVGKit: - :commit: 58543f3714b34ea66cfe58636d86dcbec3514ccf + :commit: 880c94a5b77b6f22beb491a7a7e02ace220c32af :git: https://github.com/SVGKit/SVGKit.git SPEC CHECKSUMS: @@ -131,6 +132,6 @@ SPEC CHECKSUMS: SwiftLint: dfd554ff0dff17288ee574814ccdd5cea85d76f7 SwiftMessages: 633304165351b8e3dcbb81a71f8efcd86f9c1669 -PODFILE CHECKSUM: 8b24d9f55d88a62f1c5b322c170fef2e39a3ecfe +PODFILE CHECKSUM: d765613b105112f6a6a9e2f26920db7573dcce11 COCOAPODS: 1.10.0.rc.1 From 3e5cebf2f02c629a5ec94f6b94449693d575466e Mon Sep 17 00:00:00 2001 From: weak Date: Sun, 4 Oct 2020 19:49:00 +0200 Subject: [PATCH 73/78] update SVGKit, refs #351 --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index 97bb4b1b7..ed3ef3c47 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -106,7 +106,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: SVGKit: - :commit: 880c94a5b77b6f22beb491a7a7e02ace220c32af + :commit: d1630b5c3771d305ed41de6c9f0f40503e1515d5 :git: https://github.com/SVGKit/SVGKit.git SPEC CHECKSUMS: From cb9c3ca3e43a3370cc64668f9bebd8b6ce400ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 4 Oct 2020 20:20:41 +0200 Subject: [PATCH 74/78] Preparing release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- CHANGELOG.md | 8 ++++++ .../openHABWatch (Notification).xcscheme | 25 ++++++++++++++----- .../xcschemes/openHABWatch.xcscheme | 25 ++++++++++++++----- .../openHABWatchSwift (Complication).xcscheme | 25 ++++++++++++++----- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aed18e58..87895099f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- SVGKit updated to correctly render SVG - Fix for issue #351 +- Update to Xcode 12, Swift 5.3 +- Update external dependencies, migrate to FirebaseCrashlytics, remove FirebaseAnalytics +- Update to Kingfisher 5.15.5 - to resolve clash with Alamofire +- Respond to authentication challenge in WebView + + ## [Version 2.3.24, Build 1580410444] - 2020-05-13 ### Changed diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme index b8cca27d4..7ba8fde1a 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch (Notification).xcscheme @@ -56,8 +56,10 @@ allowLocationSimulation = "YES" launchAutomaticallySubstyle = "8" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme index 449e47642..373069cd5 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatch.xcscheme @@ -55,8 +55,10 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" notificationPayloadFile = "openHABWatch Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme index 3bd32af54..85f61fb05 100644 --- a/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme +++ b/openHAB.xcodeproj/xcshareddata/xcschemes/openHABWatchSwift (Complication).xcscheme @@ -55,8 +55,10 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "32"> - + - + - + - + + + + + From 6760c725e7bc8c4639f87dceb25af67c2447c0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 4 Oct 2020 20:27:50 +0200 Subject: [PATCH 75/78] Preparing release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- Gemfile.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4944156df..b5680d030 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,17 +6,17 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.361.0) - aws-sdk-core (3.105.0) + aws-partitions (1.380.0) + aws-sdk-core (3.109.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.37.0) - aws-sdk-core (~> 3, >= 3.99.0) + aws-sdk-kms (1.39.0) + aws-sdk-core (~> 3, >= 3.109.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.79.1) - aws-sdk-core (~> 3, >= 3.104.3) + aws-sdk-s3 (1.83.0) + aws-sdk-core (~> 3, >= 3.109.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.2.2) @@ -38,13 +38,13 @@ GEM excon (0.76.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) - faraday-cookie_jar (0.0.6) - faraday (>= 0.7.4) + faraday-cookie_jar (0.0.7) + faraday (>= 0.8.0) http-cookie (~> 1.0.0) faraday_middleware (1.0.0) faraday (~> 1.0) fastimage (2.2.0) - fastlane (2.157.2) + fastlane (2.162.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) @@ -97,7 +97,7 @@ GEM google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.1) - google-cloud-storage (1.28.0) + google-cloud-storage (1.29.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) @@ -127,7 +127,7 @@ GEM naturally (2.2.0) os (1.1.1) plist (3.5.0) - public_suffix (4.0.5) + public_suffix (4.0.6) rake (13.0.1) representable (3.0.4) declarative (< 0.1.0) From 45dff6690276c60ddc69f9e87af62d83eb2dc4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 4 Oct 2020 20:34:37 +0200 Subject: [PATCH 76/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 0737ffad1..6d4a18509 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -2011,7 +2011,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2055,7 +2055,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2067,7 +2067,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2096,7 +2096,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2115,7 +2115,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2144,7 +2144,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2162,7 +2162,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2192,7 +2192,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2210,7 +2210,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2242,7 +2242,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2259,7 +2259,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2290,14 +2290,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2329,14 +2329,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2365,7 +2365,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2377,7 +2377,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2407,7 +2407,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2419,7 +2419,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2449,7 +2449,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2461,7 +2461,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2494,7 +2494,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2506,7 +2506,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2649,7 +2649,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2666,7 +2666,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2696,7 +2696,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410453; + CURRENT_PROJECT_VERSION = 1580410454; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2713,7 +2713,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.4; + MARKETING_VERSION = 2.4.5; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; From 5756ac7235155eecffc6a868ec2ed3cbef073153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 4 Oct 2020 20:35:22 +0200 Subject: [PATCH 77/78] Preparing release - step 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Müller-Seydlitz --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87895099f..610806731 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [Version 2.4.5, Build 1580410454] - 2020-10-04 + ### Fixed - SVGKit updated to correctly render SVG - Fix for issue #351 - Update to Xcode 12, Swift 5.3 From 25e72e90a7f1622ba14dd12503c7c5c55674a856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Mu=CC=88ller-Seydlitz?= Date: Sun, 4 Oct 2020 20:38:41 +0200 Subject: [PATCH 78/78] Committed version bump --- openHAB.xcodeproj/project.pbxproj | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 6d4a18509..3c2f0eaf0 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -2011,7 +2011,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2023,7 +2023,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2055,7 +2055,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2067,7 +2067,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openHABUITests; @@ -2096,7 +2096,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2115,7 +2115,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2144,7 +2144,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2162,7 +2162,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCore; @@ -2192,7 +2192,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2210,7 +2210,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2242,7 +2242,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = PBAPXHRAM9; @@ -2259,7 +2259,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.OpenHABCoreWatch; @@ -2290,14 +2290,14 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2329,14 +2329,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = openHABWatch_Extension; INFOPLIST_FILE = openHABWatch/Info.plist; - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp; @@ -2365,7 +2365,7 @@ CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2377,7 +2377,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2407,7 +2407,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; ENABLE_PREVIEWS = YES; @@ -2419,7 +2419,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab.watchkitapp.watchkitextension; @@ -2449,7 +2449,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2461,7 +2461,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2494,7 +2494,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2506,7 +2506,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.reg-labs.openHABTestsSwift"; @@ -2649,7 +2649,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2666,7 +2666,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG -Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200"; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2696,7 +2696,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1580410454; + CURRENT_PROJECT_VERSION = 1580410455; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = PBAPXHRAM9; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2713,7 +2713,7 @@ "@loader_path/../../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.4.5; + MARKETING_VERSION = 2.4.6; PRODUCT_BUNDLE_IDENTIFIER = es.spaphone.openhab; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "";