我的应用最近因以下原因被 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:
我是否在主线程中运行了任何可能导致拒绝的代码?我了解拒绝与错误处理有关。
如果是这样,我如何将相关代码移动到后台线程?
@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)") } }
最佳答案
Understanding and Analyzing Application Crash Reports告诉我们:
The exception code
0x8badf00d
indicates that an application has been terminated by iOS because a watchdog timeout occurred. The application took too long to launch, terminate, or respond to system events. One common cause of this is doing synchronous networking on the main thread. Whatever operation is on Thread 0 needs to be moved to a background thread, or processed differently, so that it does not block the main thread.
“watchdog”引用(和代码,0x8badf00d
;“吃了坏食物”哈哈)告诉你有东西阻塞了主线程(在本例中为 17.7 秒)。
您需要确定在此过程(或应用程序启动的其他地方)中的哪些内容可能会阻塞这么长时间。您可以通过识别以上哪些是同步任务来做到这一点。或者您可以使用 Instruments 中的“时间分析器”对此进行经验测试(并且您可能想尝试使用网络链接调节器来模拟非常糟糕的网络条件)。
但我同意这 Firebase issue you identified是一个可能的候选人。
关于ios - AppDelegate.Swift 上的线程处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54559883/