// // AppDelegate.swift // QuickLocation // // Created by 林 on 2026/5/25. // import UIKit import IQKeyboardManagerSwift #if !targetEnvironment(simulator) import GeYanSdk import AMapFoundationKit #endif import UMCommon @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { UIFont.loadFontName("douyu.otf") UIFont.loadFontName("zihunbiantaoti-r.ttf") setupLocation() ApiManager.shared.setup() AppRouter.shared.setup() return true } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. IAPManager.shared.startObserving() IQKeyboardManager.shared.isEnabled = true IQKeyboardManager.shared.enableAutoToolbar = false IQKeyboardManager.shared.resignOnTouchOutside = true // 微信 WXApi.registerApp(AppSettings.kAppsWXApiAppId, universalLink: AppSettings.kAppsUniversalLink) // 高德地图 #if !targetEnvironment(simulator) AMapServices.shared().apiKey = AppSettings.kAppsAMapAppId #endif // 个推 #if !targetEnvironment(simulator) GeYanSdk.setPreLoginTimeout(10) GeYanSdk.setEloginTimeout(10) GeYanSdk.start(withAppId: AppSettings.kAppsGeTuiAppId) { isSuccess, error, gtcid in print("GeYanSdk startWithAppId gtcid: \(gtcid ?? "")") } GeYanSdk.preGetToken { preDic in print("preGetToken: \(preDic)") } #endif // OpenIM GroupIMService.shared.initSDK() // 友盟 UMConfigure.initWithAppkey(AppSettings.kAppsUMengAppKey, channel: "App Store") window = UIWindow(frame: UIScreen.main.bounds) window?.backgroundColor = .white window?.overrideUserInterfaceStyle = .light window?.rootViewController = LaunchViewController() window?.makeKeyAndVisible() return true } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { print("📱 application open url: \(url.absoluteString) host: \(url.host ?? "")") // 微信 OAuth 回调:直接从 URL 提取 code,不依赖 SDK 异步 onResp if let scheme = url.scheme, scheme == "wx\(AppSettings.kAppsWXApiAppId)" || scheme == AppSettings.kAppsWXApiAppId { if let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let code = components.queryItems?.first(where: { $0.name == "code" })?.value { handleWechatLoginCode(code) return true } } // 处理支付宝支付结果(不限制 host,适应新版 SDK) if url.scheme?.hasPrefix("Alipay") == true || url.host == "safepay" { AlipaySDK.defaultService().processOrder(withPaymentResult: url) { resultDic in print("📱 Alipay callback: \(resultDic ?? [:])") guard let result = resultDic, let resultStatus = result["resultStatus"] as? String, resultStatus != "6001" else { return } if resultStatus == "9000" { NotificationCenter.default.post(name: .RequestOrderPayStatusNotification, object: nil) } } return true } // else if url.host == "pay" { return WXApi.handleOpen(url, delegate: self) // } // // return true } func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { print("📱 continue userActivity: \(userActivity.webpageURL?.absoluteString ?? "")") return WXApi.handleOpenUniversalLink(userActivity, delegate: self) } func setupLocation() { let manager = AuthorizeManager.manager(type: .locationWhenInUse) if manager?.authorizeStatus() != .authorized { manager?.authorize(nil) Permission.openAppSetting(title: "获取位置失败", message: "请在iPhone的“设置-隐私-定位”选项中允许\(kAppName)访问你的位置。") } } } extension AppDelegate { /// 重置MainTabbarViewController func showMainViewController() { window?.rootViewController = MainTabBarController() } } extension AppDelegate { static var shared: AppDelegate { UIApplication.shared.delegate as! AppDelegate } static var keyWindow: UIWindow? { UIApplication.shared.windows.filter { $0.isKeyWindow }.first } static var rootViewController: UIViewController? { getRootViewController(keyWindow?.rootViewController) } static func getRootViewController(_ inViewController: UIViewController?) -> UIViewController? { var rootViewController: UIViewController? = inViewController while inViewController?.presentedViewController != nil { rootViewController = rootViewController?.presentedViewController } guard let rootVc = rootViewController else { return nil } if rootVc.isKind(of: UINavigationController.self) { return getRootViewController((rootVc as? UINavigationController)?.visibleViewController) } else if rootVc.isKind(of: UITabBarController.self) { return getRootViewController((rootVc as? UITabBarController)?.selectedViewController) } else { return rootVc } } } extension AppDelegate: WXApiDelegate { private var handledWechatLoginCode: String? { get { objc_getAssociatedObject(self, &AssociatedKeys.handledWechatLoginCode) as? String } set { objc_setAssociatedObject(self, &AssociatedKeys.handledWechatLoginCode, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC) } } private struct AssociatedKeys { static var handledWechatLoginCode: Void? } private func handleWechatLoginCode(_ code: String) { guard code != handledWechatLoginCode else { return } handledWechatLoginCode = code LoginSessionHandler.login(type: "weixin", data: ["code": code, "code_type": ""]) } func onReq(_ req: BaseReq) { print(req) } func onResp(_ resp: BaseResp) { if let authResp = resp as? SendAuthResp, authResp.errCode == 0, let code = authResp.code { handleWechatLoginCode(code) return } if resp.isKind(of: SendAuthResp.self) { NotificationCenter.default.post(name: .resumePopupQueue, object: nil) } if resp.isKind(of: PayResp.self), let response: PayResp = resp as? PayResp { print("===================== WxPay =====================") print(response.errStr) if response.errCode == 0 { // 支付成功 DispatchQueue.global().async { DispatchQueue.main.async { } } } } } }