我的应用最近因以下原因被 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
0x8badf00dindicates 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/
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp