// /* * Copyright (c) 2022 BWI GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation @objcMembers class ValidAppVersionsDefaultService : NSObject { var currentAppVersion: String? { return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String } var updateBeforeVersion: String? { guard let data = UserDefaults.standard.data(forKey: "BWI_ValidAppVersions") else { return nil } guard let validAppVersions = try? JSONDecoder().decode(ValidAppVersions.self, from: data) else { return nil } return validAppVersions.updateBefore } var warnBeforeVersion: String? { guard let data = UserDefaults.standard.data(forKey: "BWI_ValidAppVersions") else { return nil } guard let validAppVersions = try? JSONDecoder().decode(ValidAppVersions.self, from: data) else { return nil } return validAppVersions.warnBefore } enum AppVersionState { case valid case outdated case deprecated case unknown } func versionCompare(version1: String, version2: String) -> ComparisonResult { var components1 = version1.components(separatedBy: ".") var components2 = version2.components(separatedBy: ".") if components1.count == components2.count { return version1.compare(version2, options: .numeric) } else { let zeros = Array(repeating: "0", count: abs(components1.count - components2.count)) if components1.count > components2.count { components2.append(contentsOf: zeros) } else { components1.append(contentsOf: zeros) } let normalizedVersion1 = components1.joined(separator: ".") let normalizedVersion2 = components2.joined(separator: ".") return normalizedVersion1.compare(normalizedVersion2, options: .numeric) } } func currentAppVersionState() -> AppVersionState { guard let currentAppVersion = currentAppVersion else { return .unknown } guard let updateBeforeVersion = updateBeforeVersion, let warnBeforeVersion = warnBeforeVersion else { return .valid } if versionCompare(version1: currentAppVersion, version2: updateBeforeVersion) == .orderedAscending { return .deprecated } else if versionCompare(version1: currentAppVersion, version2: warnBeforeVersion) == .orderedAscending { return .outdated } else { return .valid } } } extension ValidAppVersionsDefaultService : ValidAppVersionsService { @objc func isCurrentAppVersionOutdated() -> Bool { return currentAppVersionState() == .outdated || currentAppVersionState() == .deprecated } @objc func isCurrentAppVersionDeprecated() -> Bool { return currentAppVersionState() == .deprecated } @objc func wasOutdatedAlertShown() -> Bool { return UserDefaults.standard.bool(forKey: "BWIOutdatedAlertShown") } @objc func setOutdatedAlertShown(_ shown: Bool) { UserDefaults.standard.set(shown, forKey: "BWIOutdatedAlertShown") UserDefaults.standard.synchronize() } }