Abhishek
4 years ago
2 changed files with 162 additions and 0 deletions
@ -0,0 +1,158 @@ |
|||||||
|
// Copyright © 2015 Abhishek Banthia |
||||||
|
|
||||||
|
import Cocoa |
||||||
|
|
||||||
|
class VersionUpdateHandler: NSObject { |
||||||
|
enum VersionUpdateHandlerPriority { |
||||||
|
case defaultPri |
||||||
|
case low |
||||||
|
case medium |
||||||
|
case high |
||||||
|
} |
||||||
|
|
||||||
|
static let kSecondsInDay: Double = 86400.0 |
||||||
|
static let kMacAppStoreRefreshDelay: Double = 5.0 |
||||||
|
static let kMacRequestTimeout: Double = 60.0 |
||||||
|
static let kVersionCheckLastVersionKey = "VersionCheckLastVersionKey" |
||||||
|
static let kVersionIgnoreVersionKey = "VersionCheckIgnoreVersionKey" |
||||||
|
|
||||||
|
private var appStoreCountry: String! |
||||||
|
private var applicationVersion: String! |
||||||
|
private var applicationBundleID: String = Bundle.main.bundleIdentifier ?? "N/A" |
||||||
|
private var updatePriority: VersionUpdateHandlerPriority = VersionUpdateHandlerPriority.defaultPri |
||||||
|
private var useAllAvailableLanguages: Bool = true |
||||||
|
private var onlyPromptIfMainWindowIsAvailable: Bool = true |
||||||
|
private var checkAtLaunch: Bool = true |
||||||
|
private var checkPeriod: Float = 0.0 |
||||||
|
private var remindPeriod: Float = 1.0 |
||||||
|
private var verboseLogging: Bool = true |
||||||
|
|
||||||
|
private var showOnFirstLaunch: Bool = false |
||||||
|
public var previewMode: Bool = false |
||||||
|
private var versionDetails: String? |
||||||
|
|
||||||
|
override init() { |
||||||
|
// Setup App Store Country |
||||||
|
appStoreCountry = Locale.current.regionCode |
||||||
|
if appStoreCountry == "150" { |
||||||
|
appStoreCountry = "eu" |
||||||
|
} else if appStoreCountry.replacingOccurrences(of: "[A-Za-z]{2}", with: "", options: .regularExpression, range: appStoreCountry.startIndex ..< appStoreCountry.endIndex).count > 0 { |
||||||
|
appStoreCountry = "us" |
||||||
|
} |
||||||
|
|
||||||
|
// Setup App Version |
||||||
|
var appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String |
||||||
|
if appVersion == nil { |
||||||
|
appVersion = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String |
||||||
|
} |
||||||
|
|
||||||
|
applicationVersion = appVersion ?? "N/A" |
||||||
|
|
||||||
|
// Bundle Identifier |
||||||
|
|
||||||
|
super.init() |
||||||
|
} |
||||||
|
|
||||||
|
private func shouldCheckForNewVersion() -> Bool { |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
private func applicationLaunched() { |
||||||
|
if checkAtLaunch { |
||||||
|
checkIfNewVersion() |
||||||
|
} else if verboseLogging { |
||||||
|
print("iVersion will not check for updatess because checkAtLaunch option is disabled") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private func lastVersion() -> String { |
||||||
|
return UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) as? String ?? "" |
||||||
|
} |
||||||
|
|
||||||
|
private func setLastReminded(_ date: Date?) { |
||||||
|
UserDefaults.standard.set(date, forKey: VersionUpdateHandler.kVersionIgnoreVersionKey) |
||||||
|
} |
||||||
|
|
||||||
|
private func versionDetails(_ version: String, _ dict: [String: Any]) -> String? { |
||||||
|
if let versionData = dict[version] as? String { |
||||||
|
return versionData |
||||||
|
} else if let versionDataArray = dict[version] as? NSArray { |
||||||
|
return versionDataArray.componentsJoined(by: "\n") |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
private func setViewedVersionDetails(_ viewed: Bool) { |
||||||
|
UserDefaults.standard.set(viewed ? applicationVersion : nil, forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) |
||||||
|
} |
||||||
|
|
||||||
|
private func viewedVersionDetails() -> Bool { |
||||||
|
let lastVersionKey = UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) as? String ?? "" |
||||||
|
return lastVersionKey == applicationVersion |
||||||
|
} |
||||||
|
|
||||||
|
private func localVersionsDict() -> [String: Any] { |
||||||
|
return [String: Any]() |
||||||
|
} |
||||||
|
|
||||||
|
private func versionDetailsString() -> String { |
||||||
|
if versionDetails == nil { |
||||||
|
if viewedVersionDetails() { |
||||||
|
versionDetails = versionDetails(applicationVersion, localVersionsDict()) |
||||||
|
} |
||||||
|
} else { |
||||||
|
versionDetails = versionDetails(lastVersion(), localVersionsDict()) |
||||||
|
} |
||||||
|
|
||||||
|
return versionDetails! |
||||||
|
} |
||||||
|
|
||||||
|
private func checkIfNewVersion() { |
||||||
|
if onlyPromptIfMainWindowIsAvailable { |
||||||
|
guard NSApplication.shared.mainWindow != nil else { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
_ = Repeater(interval: .seconds(5), mode: .infinite) { _ in |
||||||
|
OperationQueue.main.addOperation { [weak self] in |
||||||
|
guard let self = self else { |
||||||
|
return |
||||||
|
} |
||||||
|
self.checkIfNewVersion() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
let lastVersionString = lastVersion() |
||||||
|
if lastVersionString.count > 0 || showOnFirstLaunch || previewMode { |
||||||
|
if applicationVersion.compareVersion(lastVersionString) == ComparisonResult.orderedDescending || previewMode { |
||||||
|
// Clear Reminder |
||||||
|
setLastReminded(nil) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
extension String { |
||||||
|
func compareVersion(_ version: String) -> ComparisonResult { |
||||||
|
return compare(version, |
||||||
|
options: CompareOptions.numeric, |
||||||
|
range: nil, |
||||||
|
locale: nil) |
||||||
|
} |
||||||
|
|
||||||
|
func compareVersionDescending(_ version: String) -> ComparisonResult { |
||||||
|
let comparsionResult = (0 - compareVersion(version).rawValue) |
||||||
|
switch comparsionResult { |
||||||
|
case -1: |
||||||
|
return ComparisonResult.orderedAscending |
||||||
|
case 0: |
||||||
|
return ComparisonResult.orderedSame |
||||||
|
case 1: |
||||||
|
return ComparisonResult.orderedDescending |
||||||
|
default: |
||||||
|
assertionFailure("Invalid Comparison Result") |
||||||
|
return .orderedSame |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue