SceneDelegate.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // SceneDelegate.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/11/6.
  6. //
  7. import UIKit
  8. import Combine
  9. import SnapKit
  10. #if DEBUG
  11. import DoraemonKit
  12. #endif
  13. class SceneDelegate: UIResponder, UIWindowSceneDelegate {
  14. var window: UIWindow?
  15. func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
  16. handleUniversalLink(userActivity: userActivity)
  17. }
  18. func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
  19. // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
  20. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
  21. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
  22. guard let sceneWindow = (scene as? UIWindowScene) else { return }
  23. window = UIWindow(windowScene: sceneWindow)
  24. window?.backgroundColor = .white
  25. window?.overrideUserInterfaceStyle = .light
  26. window?.makeKeyAndVisible()
  27. window?.rootViewController = LNNavigationController(rootViewController: LNMainViewController())
  28. LNEventDeliver.addObserver(self)
  29. autoLoginIfNeed()
  30. #if DEBUG
  31. DoraemonManager.shareInstance().install()
  32. #endif
  33. if let userActivity = connectionOptions.userActivities.first {
  34. handleUniversalLink(userActivity: userActivity)
  35. }
  36. }
  37. func sceneDidDisconnect(_ scene: UIScene) {
  38. // Called as the scene is being released by the system.
  39. // This occurs shortly after the scene enters the background, or when its session is discarded.
  40. // Release any resources associated with this scene that can be re-created the next time the scene connects.
  41. // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
  42. }
  43. func sceneDidBecomeActive(_ scene: UIScene) {
  44. // Called when the scene has moved from an inactive state to an active state.
  45. // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
  46. }
  47. func sceneWillResignActive(_ scene: UIScene) {
  48. // Called when the scene will move from an active state to an inactive state.
  49. // This may occur due to temporary interruptions (ex. an incoming phone call).
  50. }
  51. func sceneWillEnterForeground(_ scene: UIScene) {
  52. // Called as the scene transitions from the background to the foreground.
  53. // Use this method to undo the changes made on entering the background.
  54. }
  55. func sceneDidEnterBackground(_ scene: UIScene) {
  56. // Called as the scene transitions from the foreground to the background.
  57. // Use this method to save data, release shared resources, and store enough scene-specific state information
  58. // to restore the scene back to its current state.
  59. }
  60. func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
  61. if let urlContext = URLContexts.first {
  62. let url = urlContext.url
  63. LNDeeplinkManager.shared.handleDeepLink(url)
  64. }
  65. }
  66. }
  67. extension SceneDelegate: LNNetworkMonitorNotify {
  68. func onNetworkStateChanged(state: LNNetworkState) {
  69. if state == .available {
  70. autoLoginIfNeed()
  71. } else {
  72. Log.d("network invailable")
  73. }
  74. }
  75. }
  76. extension SceneDelegate: LNAppMainEvent {
  77. func onAppLanguageChanged(newLanguage: LNAppLanguage) {
  78. let nav = LNNavigationController(rootViewController: LNMainViewController())
  79. window?.rootViewController = nav
  80. nav.viewControllers.append(LNSettingsViewController())
  81. LNProfileManager.shared.reportCurrentLanguage(code: newLanguage.languageCode) { _ in }
  82. }
  83. }
  84. extension SceneDelegate: LNAccountManagerNotify {
  85. func onUserLogout() {
  86. window?.rootViewController = LNNavigationController(rootViewController: LNMainViewController())
  87. }
  88. func onUserLogin() {
  89. guard let nav = window?.rootViewController as? UINavigationController else {
  90. return
  91. }
  92. if let index = nav.viewControllers.lastIndex(where: {
  93. !($0 is LNLoginPhoneInputViewController
  94. || $0 is LNLoginCaptchaInputViewController) }) {
  95. let viewControllers = Array(nav.viewControllers[0...index])
  96. nav.setViewControllers(viewControllers, animated: true)
  97. }
  98. LNConfigManager.shared.getUpdateInfo { res in
  99. if let res, res.platform == 2, res.minVersion > curAppVersion {
  100. let cover = UIImageView(image: .icHomeTopBg)
  101. let alert = LNCommonAlertView()
  102. alert.container.insertSubview(cover, at: 0)
  103. cover.snp.makeConstraints { make in
  104. make.horizontalEdges.equalToSuperview()
  105. make.top.equalToSuperview()
  106. }
  107. alert.touchOutsideCancel = false
  108. alert.showCloseButton = false
  109. alert.titleLabel.text = .init(key: "B00058")
  110. alert.messageLabel.text = res.tip
  111. alert.messageLabel.textAlignment = .natural
  112. alert.showConfirm(.init(key: "B00139"), autoDismiss: false) {
  113. LNAppConfig.shared.jumpToAppStore()
  114. }
  115. alert.popup()
  116. } else if curTime - LNUserDefaults[.updateCheckTime, 0] > 7 * 24 * 3600 {
  117. LNAppConfig.shared.checkNewVersion { hasNew in
  118. guard hasNew else { return }
  119. let cover = UIImageView(image: .icHomeTopBg)
  120. let alert = LNCommonAlertView()
  121. alert.container.insertSubview(cover, at: 0)
  122. cover.snp.makeConstraints { make in
  123. make.horizontalEdges.equalToSuperview()
  124. make.top.equalToSuperview()
  125. }
  126. alert.titleLabel.text = .init(key: "A00392")
  127. alert.showConfirm(.init(key: "B00139")) {
  128. LNAppConfig.shared.jumpToAppStore()
  129. }
  130. alert.showCancel()
  131. alert.popup()
  132. LNUserDefaults[.updateCheckTime] = curTime
  133. }
  134. }
  135. }
  136. }
  137. }
  138. extension SceneDelegate {
  139. private func autoLoginIfNeed() {
  140. guard LNAccountManager.shared.wasLogin,
  141. LNNetworkMonitor.curState == .available else { return }
  142. LNAccountManager.shared.loginByToken()
  143. }
  144. private func handleUniversalLink(userActivity: NSUserActivity) {
  145. // 验证是否为 Universal Link
  146. guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
  147. let url = userActivity.webpageURL else {
  148. return
  149. }
  150. LNDeeplinkManager.shared.handleDeepLink(url)
  151. }
  152. }