繁体   English   中英

AppDelegate.Swift 上的线程处理

[英]Thread Handling on AppDelegate.Swift

我的应用最近因以下原因被 Apple 拒绝:

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Termination Description: SPRINGBOARD, scene-create watchdog transgression: ********* exhausted real (wall clock) time allowance of 17.77 seconds | ProcessVisibility: Foreground | ProcessState: Running | WatchdogEvent: scene-create | WatchdogVisibility: Foreground | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 37.550 (user 37.550, system 0.000), 63% CPU", | "Elapsed application CPU time (seconds): 1.015, 2% CPU" | )
Triggered by Thread:  0

以下是我的代码,即 AppDelegate:

  1. 我是否在主线程中运行了任何可能导致拒绝的代码? 我了解拒绝与错误处理有关。

  2. 如果是这样,我将如何将相关代码移动到后台线程?

     @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let font = UIFont.systemFont(ofSize: 14) let normalAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font : font, NSAttributedString.Key.foregroundColor: UIColor.white] UITabBarItem.appearance().setTitleTextAttributes(normalAttributes, for: .normal) let selectedAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font : font, NSAttributedString.Key.foregroundColor: UIColor.appYellow] UITabBarItem.appearance().setTitleTextAttributes(selectedAttributes, for: .selected) UITabBar.appearance().unselectedItemTintColor = UIColor.white GADMobileAds.configure(withApplicationID: "xxxxxx") TWTRTwitter.sharedInstance().start(withConsumerKey: "xxxxxxxxxxxxxxx", consumerSecret: "xxxxxxxxxxxxxxxxxxx") FirebaseApp.configure() let defaults: [String: Any?] = ["bet_interstitial_frequency": PlaceWagerViewController.DEFAULT_INTERSTITIAL_FREQUENCY, "event_interstitial_frequency": PlaceWagerViewController.DEFAULT_INTERSTITIAL_FREQUENCY, "rewarded_video_text": "View Ad", "scorecard_display_variant": "no_button", "unlock_icon_2": "coin"] RemoteConfig.remoteConfig().setDefaults(defaults as? [String: NSObject]) RemoteConfig.remoteConfig().fetch(completionHandler: { (status, error) in if error == nil { RemoteConfig.remoteConfig().activateFetched() } }) Messaging.messaging().delegate = self self.window = UIWindow(frame: UIScreen.main.bounds) if(Auth.auth().currentUser) == nil { openLanding() }else { openHome() } return true } func openLanding() { let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let initialViewControlleripad = storyboard.instantiateViewController(withIdentifier: "LandingViewController") self.window?.rootViewController = initialViewControlleripad self.window?.makeKeyAndVisible() } func openHome() { let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let initialViewControlleripad = storyboard.instantiateViewController(withIdentifier: "HomeTabBarController") as! UITabBarController self.window?.rootViewController = initialViewControlleripad self.window?.makeKeyAndVisible() let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: {_, _ in }) UIApplication.shared.registerForRemoteNotifications() } func handleNotification(userInfo: [AnyHashable : Any]) { let vc = self.window!.rootViewController!.topMostViewController() guard let pushType = userInfo["push_type"] as? String else { return } switch pushType { case "free_chips", "picks_sold": CashierViewController.openCashier(sender: vc) break case "bet_result": let wagerKey = userInfo["wager_id"] as? String ?? "" WagerViewController.openWager(sender: vc, wagerKey: wagerKey) break case "user_profile": let userId = userInfo["profile_id"] as? String ?? "" ProfileViewController.openPorfile(vc: vc, userId: userId) break default: break } } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as! String? if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false { return true } return false } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { print(userInfo) handleNotification(userInfo: userInfo) completionHandler(UIBackgroundFetchResult.newData) } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Unable to register for remote notifications: \\(error.localizedDescription)") } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { print("APNs token retrieved: \\(deviceToken)") } func handleDynamicLink(_ dynamicLink: DynamicLink) { guard let url = dynamicLink.url else { return } let splitLink = url.absoluteString.replacingOccurrences(of: "https://betshark.app/l/", with: "").split(separator: "/") if Auth.auth().currentUser != nil { let vc = self.window!.rootViewController!.topMostViewController() if splitLink[0] == "bet" { WagerViewController.openWager(sender: vc, wagerKey: String(splitLink[1])) } } } func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if let incomingURL = userActivity.webpageURL { let handledLink = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in guard error == nil else { print("dynmaicLink error \\(error?.localizedDescription)") return } if let dynamicLink = dynamicLink { self.handleDynamicLink(dynamicLink) } } if handledLink { return true }else { return false } } return false } } extension AppDelegate : MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { print("Firebase registration token: \\(fcmToken)") let dataDict:[String: String] = ["token": fcmToken] NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict) } func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) { print("Received data message: \\(remoteMessage.appData)") } }

理解和分析应用程序崩溃报告告诉我们:

异常代码0x8badf00d表示应用程序已被 iOS 终止,因为发生了看门狗超时。 应用程序启动、终止或响应系统事件的时间太长。 造成这种情况的一个常见原因是在主线程上进行同步网络。 线程 0 上的任何操作都需要移动到后台线程,或者进行不同的处理,以便它不会阻塞主线程。

“看门狗”参考(以及代码0x8badf00d ;“吃坏食物”哈哈)告诉你你有东西阻塞了主线程(在这个例子中为 17.7 秒)。

您需要确定在此过程中(或应用程序启动中的其他地方)可能会阻塞那么长时间的内容。 您可以通过识别以上哪些是同步任务来做到这一点。 或者,您可以使用 Instruments 中的“时间分析器”凭经验对此进行测试(您可能想尝试使用网络链路调节器来模拟非常糟糕的网络条件)。

但我同意您确定的这个Firebase 问题是一个可能的候选者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM