Commit fe6329ff by Demid Merzlyakov

IOS-155: move from a legacy isAppPro() to StoreManager to check in-app.

Use shared (group) UserDefaults to store in-app status. Use new UserDefaults key to save in-app info.
Convert existing isAppPro code to storeManager / featureAvailability controlled code.
parent 3e305001
......@@ -21,7 +21,15 @@ public class StoreManager {
// MARK: - Get known status
@UserDefaultsValue("com.inmobi.oneweather.WeatherKey", defaultValue: false, userDefaults: UserDefaults.appDefaults)
public var removeAdsPurchased: Bool
public var removeAdsPurchased: Bool {
didSet {
if removeAdsPurchased {
subscribers.invoke { subscriber in
subscriber.storeManagerUpdatedStatus(self)
}
}
}
}
public var hasSubscription: Bool {
#warning("Not implemented!")
......
......@@ -28,7 +28,8 @@ private enum ForecastCellType {
private struct HourlySection {
let rows: [ForecastCellType] = {
let showAds = !isAppPro() && AdConfigManager.shared.adConfig.adsEnabled
// TODO: use dependency injection instead of a singleton
let showAds = FeatureAvailabilityManager.shared.isAvailable(feature: .ads)
//TODO: dependency injection
if FeatureAvailabilityManager.shared.isAvailable(feature: .ads) {
return [.day, .forecastHourly, .adBanner, .precipitation, .wind, .adMREC]
......@@ -57,7 +58,7 @@ class ForecastCellFactory: CellFactory {
private let dailySection = DailySection()
private let hourlySection = HourlySection()
private var cellsToUpdate: Set<ForecastCellType> = [.forecastDaily, .forecastHourly, .forecastDailyInfo, .precipitation, .wind]
private let forecastViewModel:ForecastViewModel
private let forecastViewModel: ForecastViewModel
private var adViewCache = [TimePeriod: [IndexPath: AdView]]()
//Public
......
......@@ -157,7 +157,7 @@ extension MenuViewController: UITableViewDelegate {
extension MenuViewController: MenuViewModelDelegate {
func viewModelDidChange<P: ViewModelProtocol>(model:P) {
onMain {
if isAppPro() {
if self.viewModel.storeManager.hasSubscription || !self.viewModel.featureAvailabilityManager.isAvailable(feature: .subscription) {
self.tableView.tableHeaderView = nil
}
self.tableView.reloadData()
......
......@@ -22,8 +22,15 @@ class MenuViewModel: NSObject, ViewModelProtocol {
private var proVersionPurchaseInProgress = false
private let log = Logger(componentName: "MenuViewModel")
private var upgradeAlert: UIAlertController?
public let storeManager: StoreManager
public weak var delegate: MenuViewModelDelegate?
public init(storeManager: StoreManager = StoreManager.shared) {
self.storeManager = storeManager
super.init()
self.storeManager.add(subscriber: self)
}
public func showAlert(_ title: String?, message: String?) -> Void {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
......@@ -96,29 +103,11 @@ class MenuViewModel: NSObject, ViewModelProtocol {
self.delegate?.viewControllerForPresentation().present(alert, animated: true)
}
private let kOLAppMetricsCountKey: String = "count"
private let kOLAppMetricsDateKey: String = "date"
private func logEventToUserDefaults(forKey eventKey: String) {
let userDefaults = UserDefaults.standard
var updatedCount: Int = 1
var metricsLog = userDefaults.dictionary(forKey: kOLAppMetricsKey) ?? [String : Any]()
if let countEvent = metricsLog[eventKey] as? [String : Any], let count = countEvent[kOLAppMetricsCountKey] as? Int {
updatedCount = count + 1
}
let updateEvent = [kOLAppMetricsCountKey: updatedCount, kOLAppMetricsDateKey: Date()] as [String : Any]
metricsLog[eventKey] = updateEvent
userDefaults.set(metricsLog, forKey: kOLAppMetricsKey)
}
private func updateToProCompleted() {
logEventToUserDefaults(forKey: kEventInAppPurchasedCompleted)
NotificationCenter.default.post(name: Notification.Name(rawValue: kEventInAppPurchasedCompleted), object: nil)
storeManager.removeAdsPurchased = true
analytics(log: .ANALYTICS_GO_PRO)
delegate?.viewModelDidChange(model: self)
}
......@@ -126,7 +115,7 @@ class MenuViewModel: NSObject, ViewModelProtocol {
// MARK: - Help section
extension MenuViewModel {
private var featureAvailabilityManager: FeatureAvailabilityManager {
public var featureAvailabilityManager: FeatureAvailabilityManager {
FeatureAvailabilityManager.shared
}
......@@ -175,7 +164,7 @@ extension MenuViewModel {
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!
let build = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")!
let systemVersion = UIDevice.current.systemVersion
let isPro = isAppPro() ? "Yes" : "No"
let isPro = storeManager.removeAdsPurchased ? "Yes" : "No"
let installedDate = "Unknown"
let deviceInfo = "Version: \(version)-\(build)\nDevice: \(deviceName)\nOS: \(systemVersion)\nPro: \(isPro) \nInstalled: \(installedDate) \(deviceToken)"
......@@ -292,3 +281,11 @@ extension MenuViewModel: OLInAppStoreManagerUIDelegate {
return delegate.viewControllerForPresentation()
}
}
extension MenuViewModel: StoreManagerSubscriber {
func storeManagerUpdatedStatus(_ storeManager: StoreManager) {
onMain {
self.delegate?.viewModelDidChange(model: self)
}
}
}
......@@ -13,18 +13,25 @@ class NWSAlertViewModel: ViewModelProtocol {
public private(set) var alert: NWSAlert
private let alertsManager: NWSAlertsManager
public var cellFactory: NWSAlertCellFactory
private let featureAvailabilityManager: FeatureAvailabilityManager
private let storeManager: StoreManager
deinit {
alertsManager.delegates.remove(delegate: self)
NotificationCenter.default.removeObserver(self)
}
public init(alert: NWSAlert, alertsManager: NWSAlertsManager = LocationManager.shared.nwsAlertsManager) {
public init(alert: NWSAlert,
alertsManager: NWSAlertsManager = LocationManager.shared.nwsAlertsManager,
featureAvailabilityManager: FeatureAvailabilityManager = FeatureAvailabilityManager.shared,
storeManager: StoreManager = StoreManager.shared) {
self.alert = alert
self.alertsManager = alertsManager
cellFactory = NWSAlertCellFactory(alert: alert)
self.featureAvailabilityManager = featureAvailabilityManager
self.storeManager = storeManager
alertsManager.delegates.add(delegate: self)
NotificationCenter.default.addObserver(self, selector: #selector(handlePremiumStateChange), name: Notification.Name(rawValue: kEventInAppPurchasedCompleted), object: nil)
self.storeManager.add(subscriber: self)
cellFactory.delegate = self
}
......@@ -57,3 +64,9 @@ extension NWSAlertViewModel: CellFactoryDelegate {
}
}
extension NWSAlertViewModel: StoreManagerSubscriber {
func storeManagerUpdatedStatus(_ storeManager: StoreManager) {
handlePremiumStateChange()
}
}
......@@ -23,6 +23,7 @@ class TodayViewModel: ViewModelProtocol {
//Private
private let locationManager: LocationManager
private let configManager: ConfigManager
private let storeManager: StoreManager
private let kAnalyticsThresholdSec = 2.5
private let log = Logger(componentName: "TodayViewModel")
private var ccpaHelper = CCPAHelper.shared
......@@ -51,15 +52,16 @@ class TodayViewModel: ViewModelProtocol {
NotificationCenter.default.removeObserver(self)
}
public init(locationManager: LocationManager = LocationManager.shared, configManager: ConfigManager = ConfigManager.shared, shortsManager: ShortsManager = ShortsManager.shared) {
public init(locationManager: LocationManager = LocationManager.shared, configManager: ConfigManager = ConfigManager.shared, shortsManager: ShortsManager = ShortsManager.shared, storeManager: StoreManager = StoreManager.shared) {
self.locationManager = locationManager
self.configManager = configManager
self.shortsManager = shortsManager
self.storeManager = storeManager
self.storeManager.add(subscriber: self)
self.shortsManager.multicastDelegate.add(delegate: self)
self.location = locationManager.selectedLocation
locationManager.add(delegate: self)
Settings.shared.delegate.add(delegate: self)
NotificationCenter.default.addObserver(self, selector: #selector(handlePremiumStateChange), name: Notification.Name(rawValue: kEventInAppPurchasedCompleted), object: nil)
}
//MARK: Private
......@@ -77,7 +79,7 @@ class TodayViewModel: ViewModelProtocol {
guard !adManager.initialized else { return }
self.ccpaHelper.updateCCPAStatus(reason: "initialization")
if !isAppPro() {
if self.featureAvailabilityManager.isAvailable(feature: .ads) {
// In Debug mode we allow the user to change the environment
//TODO AdStack: add MoPub App Key
......@@ -195,6 +197,12 @@ extension TodayViewModel: LocationManagerDelegate {
}
}
extension TodayViewModel: StoreManagerSubscriber {
func storeManagerUpdatedStatus(_ storeManager: StoreManager) {
handlePremiumStateChange()
}
}
//MARK:- Settings Delegate
extension TodayViewModel: SettingsDelegate {
func settingsDidChange() {
......
......@@ -9,11 +9,9 @@ import Foundation
public let kMoEngageAppId = "11PSBEC6K93IYU1AC8WIYADY"
public let kEventInAppPurchasedCompleted = "EventInAppPurchasedCompleted"
public let a9AppKey = "2e440b094f7c44b4bae7044b764c61ac"
public let kAdMoPubInitializationAdUnitId = "05bff78d4a4245bd98ff6b595c134889"
public let kFlurryPartnerId = "2HJTQGPKT6VHXYRHFQTD"
public let kOLAppMetricsKey: String = "OLAppMetricsKey"
public let WDT_APP_ID = "e3b73414"
public let WDT_APP_KEY = "25e8d6b72de3bcd528f7769b073cc335"
......
......@@ -21,14 +21,6 @@ let BLANK = "--"
let UP_ARROW = "\u{2191}"
let DOWN_ARROW = "\u{2193}"
// isPro
public func isAppPro() -> Bool {
if let metricsLog = UserDefaults.standard.dictionary(forKey: kOLAppMetricsKey) {
return metricsLog[kEventInAppPurchasedCompleted] != nil
}
return false
}
func windUnits() -> WindUnits {
return .mps
}
......
......@@ -20,6 +20,33 @@ extension UserDefaults {
return UserDefaults.standard
}
private static func migrateInAppPurchaseMarker() {
// User Defaults - Old
let userDefaults = UserDefaults.standard
// App Groups Default - New
let groupDefaults = UserDefaults.appDefaults
let legacyAppMetricsKey = "OLAppMetricsKey"
let legacyInAppPurchaseEventKey = "EventInAppPurchasedCompleted"
let newInAppPurchaseMarkerKey = "com.inmobi.oneweather.WeatherKey" // we want something inconspicuous just so that it wasn't that obvious if anybody has a look at UserDefaults
var hasInAppPurchase = false
for userDefaults in [groupDefaults, userDefaults] {
if let appMetrics = userDefaults.dictionary(forKey: legacyAppMetricsKey) {
if appMetrics[legacyInAppPurchaseEventKey] != nil {
hasInAppPurchase = true
break
}
}
}
if hasInAppPurchase {
groupDefaults.set(true, forKey: newInAppPurchaseMarkerKey)
}
}
public static func migrateUserDefaultsToAppGroupsIfNeeded() {
// User Defaults - Old
let userDefaults = UserDefaults.standard
......@@ -41,5 +68,8 @@ extension UserDefaults {
} else {
log.info("No need to migrate defaults")
}
// Migrate in app purchase marker separately, because it was added later.
migrateInAppPurchaseMarker()
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment