Files
suixinkan_uikit/suixinkan/SceneDelegate.swift

145 lines
4.8 KiB
Swift

//
// SceneDelegate.swift
// suixinkan
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
private var sessionExpiredDialog: SessionExpiredDialogViewController?
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
guard let windowScene = scene as? UIWindowScene else { return }
AppNavigationBarAppearance.applyGlobalAppearance()
let window = UIWindow(windowScene: windowScene)
window.rootViewController = AppRouter.makeRootViewController()
window.makeKeyAndVisible()
self.window = window
(UIApplication.shared.delegate as? AppDelegate)?.window = window
PushNotificationManager.shared.attach(window: window)
registerNotifications()
if AppStore.shared.session.isLoggedIn {
DispatchQueue.main.async {
PushNotificationManager.shared.handleLoginCompleted()
}
}
if let response = connectionOptions.notificationResponse {
PushNotificationManager.shared.handleNotificationResponse(response)
}
}
func sceneDidDisconnect(_ scene: UIScene) {
NotificationCenter.default.removeObserver(self)
if (UIApplication.shared.delegate as? AppDelegate)?.window === window {
(UIApplication.shared.delegate as? AppDelegate)?.window = nil
}
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
_ = WeChatManager.shared.handleOpenURL(url)
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
_ = WeChatManager.shared.handleContinueUserActivity(userActivity)
}
func sceneDidBecomeActive(_ scene: UIScene) {
PushNotificationManager.shared.retryPendingRegistrationUpload()
}
private func registerNotifications() {
NotificationCenter.default.addObserver(
self,
selector: #selector(handleSessionDidExpire),
name: NotificationName.sessionDidExpire,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleUserDidLogout),
name: NotificationName.userDidLogout,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleUserDidLogin),
name: NotificationName.userDidLogin,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleAccountDidSwitch),
name: NotificationName.accountDidSwitch,
object: nil
)
}
@objc private func handleSessionDidExpire() {
guard AppStore.shared.session.isLoggedIn else { return }
guard sessionExpiredDialog == nil else { return }
GlobalLoadingManager.shared.hideAll()
let dialog = SessionExpiredDialogViewController { [weak self] in
self?.transitionToLogin()
}
sessionExpiredDialog = dialog
guard let presenter = topViewController(from: window?.rootViewController) else {
sessionExpiredDialog = nil
return
}
presenter.present(dialog, animated: true)
}
private func transitionToLogin() {
sessionExpiredDialog = nil
PushNotificationManager.shared.handleLogout()
AppStore.shared.logout()
AppRouter.setRoot(.login, on: window)
}
@objc private func handleUserDidLogout() {
transitionToLogin()
}
@objc private func handleUserDidLogin() {
sessionExpiredDialog?.dismiss(animated: false)
sessionExpiredDialog = nil
AppRouter.setRoot(.mainTab, on: window)
DispatchQueue.main.async {
PushNotificationManager.shared.handleLoginCompleted()
PushNotificationManager.shared.routePendingNotificationIfPossible()
}
}
@objc private func handleAccountDidSwitch() {
PushNotificationManager.shared.handleAccountSwitched()
}
private func topViewController(from viewController: UIViewController?) -> UIViewController? {
guard let viewController else { return nil }
if let presented = viewController.presentedViewController {
return topViewController(from: presented)
}
if let navigationController = viewController as? UINavigationController {
return topViewController(from: navigationController.visibleViewController)
}
if let tabBarController = viewController as? UITabBarController {
return topViewController(from: tabBarController.selectedViewController)
}
return viewController
}
}