kstenerud / KSCrash

The Ultimate iOS Crash Reporter
MIT License
4.23k stars 705 forks source link

Get crash report when it crash #525

Closed baiyidjp closed 1 month ago

baiyidjp commented 2 months ago

I want to get the crash report when it crashes or cold starts, and upload it manually to our server. How can I do it?

The KSCrash version I use is pod 'KSCrash', '~> 2.0.0-alpha.4'

GLinnik21 commented 2 months ago

Hi! Did you try the standard installation from the README?

baiyidjp commented 2 months ago

Hi! Did you try the standard installation from the README?

    let installation = CrashInstallationConsole.shared()
    installation.printAppleFormat = true

    let config = KSCrashConfiguration()
    installation.install(with: config)

    for reportId in KSCrash.shared().reportIDs {
      guard let report = KSCrash.shared().report(for: Int64(truncating: reportId)) else {
        continue
      }
      let filter = CrashReportFilterAppleFmt(reportStyle: .unsymbolicated)
      filter.filterReports([report]) { reports, completed, error in
        if let firstReport = reports?.first, let reportString = firstReport.stringValue {
          debugPrint("KSCrash\n\r", reportString)
          KSCrash.shared().deleteReport(with: Int64(truncating: reportId))
        }
      }
    }

I found the unreported crash during cold start and converted it to a String. Because report.stringValue was nil when I directly took it, I converted it through a filter. Is this the correct procedure?

baiyidjp commented 2 months ago

@GLinnik21

I can use .unsymbolicated to get unsymbolicated stringValue, but How to set it if you don't want to automatically symbolize when capturing crash?

GLinnik21 commented 2 months ago

Because report.stringValue was nil when I directly took it

The KSCrashReport is a new API introduced by @bamx23. It was primarily created for internal use, so exposing it in the public API might have been misleading for users. Typically, crash reports are in a JSON-like dictionary format, so stringValue is expected to be empty. What you likely need is dictionaryValue. Since it's in a JSON-like format, you can convert it to JSON with any converter and send it as a string to your server. You don't necessarily need to use Filters to get a string value, or the Installations module at all. If you need this custom behavior, you might consider using just the KSCrash/Recording module and utilize the API exposed in KSCrash.h. This would give you more direct control over the crash reports.

For example, you could do something like this:

if let report = KSCrash.shared().report(for: reportId),
   let value = report.dictionaryValue,
   let jsonData = try? JSONSerialization.data(withJSONObject: value, options: []),
   let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
    // Send jsonString to your server
}

This approach should give you the raw crash report data in a string format that you can easily send to your server.

How to set it if you don't want to automatically symbolize when capturing crash?

If you need raw addresses, you can get them from dictionaryValue alongside the symbolicated values. Why don't you need symbolication?

GLinnik21 commented 2 months ago

The KSCrash version I use is pod 'KSCrash', '~> 2.0.0-alpha.4'

It's worth noting that you're using an alpha version of KSCrash. This version is not stable, and the API may change.

For production, it's recommended to use the latest stable 1.x version (currently 1.17.4):

pod 'KSCrash', '~> 1.17.4'

However, be aware that the API in 1.x versions differs slightly from the 2.0.0-alpha version. If you switch, you'll need to adjust your code for the version you're using.