// // KMLightMemberManager.swift // PDF Reader Pro // // Created by lizhe on 2023/2/22. // import Cocoa let USER_LOGINSTATE_NOTIFICATION = "kUserLoginStateNotification" //用户登录状态改变通知 let USER_INFO_CHANGE_NOTIFICATION = "kUserInfoChangeNotification" //用户信息改变通知 let ADVANCED_NOTIFICATION = "kAdvancedContentViewShowNotification" //用户高级引导显示 @objc enum KMLightMemberUserState: Int, CaseIterable { case unknown = 0//,"unknown" case login = 1//"login" //登录 case logOut = 2//"logOut" //登出 case cancellation = 3//"cancellation" //注销 } @objcMembers class KMLightMemberManager: NSObject { static let manager = KMLightMemberManager() var config: KMLightMemberConfig = KMLightMemberConfig() var info: KMLightMemberUserInfo = KMLightMemberUserInfo() var token: KMLightMemberToken = KMLightMemberToken() var userState: KMLightMemberUserState = .unknown //用户状态 var purchaseState: KMPurchaseManagerState { //订阅状态 get { return KMPurchaseManager.manager.state } } /** 是否显示高级功能视图 */ var canShowAdvancedView: Bool = true { didSet { NotificationCenter.default.post(name: NSNotification.Name(rawValue: ADVANCED_NOTIFICATION), object: nil) } } override init() { super.init() self.reloadUserInfo() } func logOut() { DispatchQueue.main.async { self.userState = .logOut KMLightMemberCache.cache.clean() self.reloadUserInfo() NotificationCenter.default.post(name: NSNotification.Name(rawValue: USER_LOGINSTATE_NOTIFICATION), object: nil, userInfo: nil) } } func logIn() { self.userState = .login self.reloadUserInfo() NotificationCenter.default.post(name: NSNotification.Name(rawValue: USER_LOGINSTATE_NOTIFICATION), object: nil, userInfo: nil) } func cancellation() { self.userState = .cancellation self.reloadUserInfo() NotificationCenter.default.post(name: NSNotification.Name(rawValue: USER_LOGINSTATE_NOTIFICATION), object: nil, userInfo: nil) } } //MARK: - 数据 extension KMLightMemberManager { /** 刷新本地用户数据 */ func reloadUserInfo() { //获取用户信息 let userInfo = KMLightMemberCache.cache.readData(type: .info) if userInfo.count != 0 { KMLightMemberUserInfo.parseData(data: userInfo, needSave: false) { [weak self] data in self?.info = data } } else { self.info = KMLightMemberUserInfo() } let token = KMLightMemberCache.cache.readData(type: .token) if token.count != 0 { KMLightMemberToken.parseData(data: token) { [weak self] data in self?.token = data } } else { self.token = KMLightMemberToken() } NotificationCenter.default.post(name: NSNotification.Name(rawValue: USER_INFO_CHANGE_NOTIFICATION), object: nil, userInfo: nil) } /** 刷新本地用户数据 */ func updateNetworkingUserInfo(completion: @escaping (_ isDidLogout: Bool) -> Void) { KMRequestServerManager.manager.getUserInfo { [weak self] success, data, error, isLocal in if success { self?.reloadUserInfo() completion(false) } else { if error?.code == 304 { KMLightMemberManager.manager.logOut() completion(true) } completion(false) } } } /** token是否生效 */ func isTokenValid() async -> Bool { var result = false if self.isLogin() { do { let (success, error) = try await KMRequestServerManager.manager.getUserInfo2() // Thread.sleep(forTimeInterval: 20.0) if success { result = true } else { if error.code == 304 { KMLightMemberManager.manager.logOut() result = false } else { result = true } } return result } catch { return result } } return result } } //MARK: - 快捷方法 extension KMLightMemberManager { //是否已经登录 func isLogin() -> Bool { var result: Bool = false if token.access_token != "" { result = true } return result } //是否已经注销 func isLogOff() -> Bool { var result: Bool = false return result } //是否能使用高级功能 func canUseAdvanced(needNetworking: Bool = false) async -> Bool { var result: Bool = false var tokenValid = true if needNetworking { tokenValid = await self.isTokenValid() } KMPrint(tokenValid) if tokenValid && info.isInFreeUseTime || (self.purchaseState == .subscription || self.purchaseState == .trial) { result = true } return result } // //是否能使用付费功能 // func canPayFunction(needNetworking: Bool = false) async -> Bool { // var result: Bool = false // //先确认可以使用高级功能,再确认是否已经订阅 // if await self.canUseAdvanced(needNetworking: needNetworking) && (self.purchaseState == .subscription || self.purchaseState == .trial) { // result = true // } // return result // } //是否能使用付费功能 func canPayFunction() -> Bool { var result: Bool = false //先确认可以使用高级功能,再确认是否已经订阅 if (self.purchaseState == .subscription || self.purchaseState == .trial) { result = true } return result } //是否显示订单信息 func existOrderInfo() -> Bool { return self.info.existOrderInfo ?? false } } //MARK: 登录注册界面弹出逻辑 /* 弹出策略: 每日首次进入阅读页,自动弹出【注册弹窗】;关闭弹窗后,当日不再弹出,次日零点重置 注意:首次进入阅读页之前,通过其他方式弹出过【注册弹窗】,则进入阅读页不再主动弹出 **/ extension KMLightMemberManager { //检查是否需要弹起注册登录框 func checkPopupRegister() -> Bool { var needPop = false self.resetRegisterPopupStatus() var info: [String : Any] = [:] if (UserDefaults.standard.value(forKey: "CheckPopupRegistration") == nil) { } else { info = (UserDefaults.standard.value(forKey: "CheckPopupRegistration") as! [String : Any]) } let isPopupShownToday = info["isPopupShownToday"] as? Bool ?? false var lastPopupDate = info["lastPopupDate"] as? Date // 检查是否已经弹出过注册弹窗 if (!isPopupShownToday) { // 获取当前日期 let currentDate = Date() // 检查上次弹窗显示的日期是否为空,或者不是当天 if lastPopupDate == nil || (lastPopupDate != nil && !Calendar.current.isDate(lastPopupDate!, inSameDayAs: currentDate)) { // 更新上次弹窗显示的日期为当前日期 lastPopupDate = currentDate info.updateValue(lastPopupDate!, forKey: "lastPopupDate") info.updateValue(true, forKey: "isPopupShownToday") UserDefaults.standard.set(info, forKey: "CheckPopupRegistration") UserDefaults.standard.synchronize() needPop = true } } return needPop } func updatePopupShownToday(isPop: Bool) { var info: [String : Any] = [:] if (UserDefaults.standard.value(forKey: "CheckPopupRegistration") == nil) { } else { info = (UserDefaults.standard.value(forKey: "CheckPopupRegistration") as! [String : Any]) } info.updateValue(isPop, forKey: "isPopupShownToday") UserDefaults.standard.set(info, forKey: "CheckPopupRegistration") UserDefaults.standard.synchronize() } func resetRegisterPopupStatus() { var info: [String : Any] = [:] if (UserDefaults.standard.value(forKey: "CheckPopupRegistration") == nil) { } else { info = (UserDefaults.standard.value(forKey: "CheckPopupRegistration") as! [String : Any]) } var isPopupShownToday = info["isPopupShownToday"] let lastPopupDate = info["lastPopupDate"] as? Date // 获取当前日期和时间 let currentDate = Date() // 获取当前日历 let calendar = Calendar.current // 获取当天的午夜时间 let midnight = calendar.startOfDay(for: currentDate) // 检查上次弹窗显示的日期是否早于当天的午夜时间 if let lastPopupDate = lastPopupDate, lastPopupDate < midnight { // 重置弹窗状态 isPopupShownToday = false info.updateValue(isPopupShownToday!, forKey: "isPopupShownToday") // info.updateValue(NSDate(), forKey: "lastPopupDate") UserDefaults.standard.set(info, forKey: "CheckPopupRegistration") UserDefaults.standard.synchronize() } } }