Skip to content

Instantly share code, notes, and snippets.

@adriatikgashi
Created May 14, 2020 15:37
Show Gist options
  • Save adriatikgashi/046a165134933506772a8361f2e2f6a1 to your computer and use it in GitHub Desktop.
Save adriatikgashi/046a165134933506772a8361f2e2f6a1 to your computer and use it in GitHub Desktop.
import Foundation
import FirebaseRemoteConfig
class ForceUpdateManager {
// MARK: - Static
static var shared: ForceUpdateManager = ForceUpdateManager()
var callback: ((_ appStoreUrl: String, _ isRequired: Bool) -> Void)?
// MARK: - Default Values
private let kAppStoreURL: String = "YOUR_APP_STORE_APP_URL"
private let kCurrentVersion: String = "1.0.0"
// MARK: - Private Enum
private enum RemoteConfigKeys: String {
case appStoreUrl = "iOS_app_store_url",
currentVersion = "iOS_update_current_version",
updateRequired = "iOS_update_required"
}
// MARK: - Private Properties
private var remoteConfig: RemoteConfig
// MARK: - Constants
private let kNumberOfSecondsToFetchData: TimeInterval = 60.0
// MARK: - Init
init(remoteConfig: RemoteConfig = .remoteConfig()) {
self.remoteConfig = remoteConfig
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = .zero
remoteConfig.configSettings = settings
let appDefaults: [String : Any?] = [
RemoteConfigKeys.appStoreUrl.rawValue: kAppStoreURL,
RemoteConfigKeys.currentVersion.rawValue: kCurrentVersion,
RemoteConfigKeys.updateRequired.rawValue: false
]
remoteConfig.setDefaults(appDefaults as? [String: NSObject])
}
// MARK: - Start
func start() {
remoteConfig.fetch(withExpirationDuration: kNumberOfSecondsToFetchData) { [unowned self] (status, error) -> Void in
if error != nil {
self.log(message: "An error ocurred while fetching from RemoteConfig, Error: \(error?.localizedDescription ?? "Unknown")")
return
}
switch status {
case .success:
self.log(message: "ConfigStatus success!")
self.activateRemoteConfig()
case .failure:
self.log(message: "ConfigStatus failure!")
case .noFetchYet:
self.log(message: "ConfigStatus noFetchYet!")
case .throttled:
self.log(message: "ConfigStatus throttled!")
@unknown default: break
}
}
}
private func activateRemoteConfig() {
remoteConfig.activate { [unowned self] (_) in
self.log(message: "Activated!")
let appStoreUrl = self.remoteConfig[ForceUpdateManager.RemoteConfigKeys.appStoreUrl.rawValue].stringValue ?? self.kAppStoreURL
let remoteAppVersion = self.remoteConfig[ForceUpdateManager.RemoteConfigKeys.currentVersion.rawValue].stringValue ?? self.kCurrentVersion
let updateRequired = self.remoteConfig[ForceUpdateManager.RemoteConfigKeys.updateRequired.rawValue].boolValue
self.showNewUpdateNeeded(remoteAppVersion: AppVersion(remoteAppVersion), appStoreUrl: appStoreUrl, isRequired: updateRequired)
}
}
private func showNewUpdateNeeded(remoteAppVersion: AppVersion, appStoreUrl: String, isRequired: Bool) {
let localAppVersion = AppVersion(installedAppVersion())
if remoteAppVersion.compare(to: localAppVersion) == .greater {
callback?(appStoreUrl, isRequired)
}
}
private func log(message: String) {
debugPrint("[ForceUpdateManager]: \(message)")
}
}
// MARK: - Utils
extension ForceUpdateManager {
private func installedAppVersion() -> String {
return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment