我已经搜索了一圈,但是还没有找到一个不需要指向第三方服务的答案。我只需要在 NSUserDefaults
中保存一个值,这样当下次打开应用程序时,我就可以显示一个警报,说明应用程序已经崩溃了。
谢谢。
我已经搜索了一圈,但是还没有找到一个不需要指向第三方服务的答案。我只需要在 NSUserDefaults
中保存一个值,这样当下次打开应用程序时,我就可以显示一个警报,说明应用程序已经崩溃了。
谢谢。
applicationWillTerminate
函数仅在应用程序正常关闭时运行。原生检测应用程序崩溃的代码如下所示。
全局定义变量let crashedNotificationKey = "com.stackoverflow.crashNotificationKey"
var crashedLastTime = true
应用代理
func applicationWillTerminate(application: UIApplication) {
crashedLastTime = false
prefs.setBool(crashedLastTime, forKey: "crash")
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
crashedLastTime = prefs.boolForKey("crash")
if crashedLastTime == true {
crashedLastTime = false
prefs.setBool(crashedLastTime, forKey: "crash")
NSNotificationCenter.defaultCenter().postNotificationName(crashedNotificationKey, object: self)
} else {
crashedLastTime = true
prefs.setBool(crashedLastTime, forKey: "crash")
}
return true
}
根视图控制器
override func awakeFromNib() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "crashedAlert", name: crashedNotificationKey, object: nil)
}
func crashedAlert() {
let alert = UIAlertController(title: "The app has crashed!", message: "Sorry about that! I am just a 17 year old highschooler making my first game!", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "It's cool bro.", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
true
。例如:prefs.setBool(true, forKey: "crash")。 - AwesomenessapplicationWillTerminate
。 - JackapplicationWilTerminate
方法不会被调用。 - Andrew BennetapplicationWillResignActive
在用户能够强制退出之前被调用,因此应用程序在用户能够强制退出之前处于非活动状态。我跟踪应用程序状态,并且仅当最后已知状态为活动状态时才将崩溃视为崩溃。当状态为非活动状态或后台状态时,即使实际上崩溃了而不是仅强制退出,它也不会过多地打扰用户。 - Gerd CastanapplicationWillTerminate
方法。事实并非如此,请参阅applicationWillTerminate
的文档。 - HangarRashhttps://github.com/zixun/CrashEye/blob/master/CrashEye/Classes/CrashEye.swift
!!! 不要忘记复制(或安装Pod)解决方案代码 !!!
AppDelegate.swift
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
CrashEye.add(delegate: self)
return true
}
}
extension AppDelegate: CrashEyeDelegate {
func crashEyeDidCatchCrash(with model: CrashModel) {
UserDefaults.standard.set(model.reason + "(\(Date()))", forKey: "crash")
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 40, y: 40, width: 80, height: 44))
button.setTitle("BOOOM", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(boomButtonTouchedUpInside), for: .touchUpInside)
view.addSubview(button)
}
override func viewDidAppear(_ animated: Bool) {
if let date = UserDefaults.standard.string(forKey: "crash") {
let alert = UIAlertController(title: "", message: date, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true)
}
}
@objc func boomButtonTouchedUpInside(_ sender: Any) {
let arr = [1, 2, 3]
let elem = arr[4]
}
}
AppDelegate.swift
import UIKit
import Fabric
import Crashlytics
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Crashlytics.sharedInstance().delegate = self
Fabric.with([Crashlytics.self])
return true
}
}
extension AppDelegate: CrashlyticsDelegate {
func crashlyticsDidDetectReport(forLastExecution report: CLSReport) {
let alert = UIAlertController(title: "\(report.dateCreated)", message: report.identifier, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
DispatchQueue.global(qos: .background).async {
sleep(3)
DispatchQueue.main.async {
self.window?.rootViewController?.present(alert, animated: true)
}
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 40, y: 40, width: 80, height: 44))
button.setTitle("BOOOM", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(boomButtonTouchedUpInside), for: .touchUpInside)
view.addSubview(button)
}
@objc func boomButtonTouchedUpInside(_ sender: Any) {
let arr = [1, 2, 3]
let elem = arr[4]
}
}
applicationWillResignActive
,但是即使应用程序崩溃,它也会运行。 - zennoxapplicationWillTerminate
和applicationDidEnterBackground
这样的函数可以做到这一点。 - Ryan Collins如果你不使用已被弃用的Fabric
,你需要在你的ViewController
中使用以下代码,该代码在升级到Firebase Crashlytics SDK中有提到。
我是这样使用的:
// 1. import Crashlytics
import FirebaseCrashlytics
class YOUR_ROOT_VIEW_CONTROLLER {
override viewDidLoad(){
//...
// 2. register to get the notifications
self.configCrashlytics()
// ...
}
func configCrashlytics() {
/* You must set setCrashlyticsCollectionEnabled to false in order to use
checkForUnsentReportsWithCompletion. */
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
Crashlytics.crashlytics().checkForUnsentReports { hasUnsentReport in
let hasUserConsent = false
// ...get user consent.
if hasUserConsent && hasUnsentReport {
Crashlytics.crashlytics().sendUnsentReports()
} else {
Crashlytics.crashlytics().deleteUnsentReports()
}
}
// Detect when a crash happens during your app's last run.
if Crashlytics.crashlytics().didCrashDuringPreviousExecution() {
// ...notify the user that last time the app crashed
}
}
// 4. Add a button that run fatallError()
@IBAction func crashApp(_ sender: UIButton) {
fatalError()
}
}
Crashlytics.crashlytics().didCrashDuringPreviousExecution()
- Coder ACJHP