簡體   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