2018-12-17 22:44:06 -08:00
|
|
|
|
//
|
|
|
|
|
// CrashReporter.swift
|
|
|
|
|
// NetNewsWire
|
|
|
|
|
//
|
|
|
|
|
// Created by Brent Simmons on 12/17/18.
|
|
|
|
|
// Copyright © 2018 Ranchero Software. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import Foundation
|
2024-04-01 19:31:57 -07:00
|
|
|
|
import Web
|
2020-12-11 18:09:36 -06:00
|
|
|
|
import CrashReporter
|
2018-12-17 22:44:06 -08:00
|
|
|
|
|
|
|
|
|
// Displays a window that shows the crash log — gives the user the chance to add data.
|
|
|
|
|
// (Or just decide not to send it.)
|
|
|
|
|
// This code is not included in the MAS build.
|
|
|
|
|
// At some point this code should probably move into RSCore, so Rainier and any other
|
|
|
|
|
// future apps can use it.
|
|
|
|
|
|
2024-03-19 23:05:30 -07:00
|
|
|
|
@MainActor struct CrashReporter {
|
2018-12-20 22:21:42 -08:00
|
|
|
|
|
2018-12-22 12:01:31 -08:00
|
|
|
|
struct DefaultsKey {
|
|
|
|
|
static let sendCrashLogsAutomaticallyKey = "SendCrashLogsAutomatically"
|
2018-12-20 22:21:42 -08:00
|
|
|
|
}
|
2018-12-17 22:44:06 -08:00
|
|
|
|
|
2019-01-11 22:50:36 -08:00
|
|
|
|
private static var crashReportWindowController: CrashReportWindowController?
|
|
|
|
|
|
2018-12-17 22:44:06 -08:00
|
|
|
|
/// Look in ~/Library/Logs/DiagnosticReports/ for a new crash log for this app.
|
2018-12-22 12:01:31 -08:00
|
|
|
|
/// Show a crash log reporter window if found.
|
2020-12-11 18:09:36 -06:00
|
|
|
|
static func check(crashReporter: PLCrashReporter) {
|
|
|
|
|
guard crashReporter.hasPendingCrashReport(),
|
|
|
|
|
let crashData = crashReporter.loadPendingCrashReportData(),
|
|
|
|
|
let crashReport = try? PLCrashReport(data: crashData),
|
|
|
|
|
let crashLogText = PLCrashReportTextFormatter.stringValue(for: crashReport, with: PLCrashReportTextFormatiOS) else { return }
|
2018-12-17 22:44:06 -08:00
|
|
|
|
|
2018-12-22 12:01:31 -08:00
|
|
|
|
if shouldSendCrashLogsAutomatically() {
|
2020-12-11 18:09:36 -06:00
|
|
|
|
sendCrashLogText(crashLogText)
|
|
|
|
|
} else {
|
|
|
|
|
runCrashReporterWindow(crashLogText)
|
2018-12-20 22:21:42 -08:00
|
|
|
|
}
|
2020-12-11 18:09:36 -06:00
|
|
|
|
|
|
|
|
|
crashReporter.purgePendingCrashReport()
|
2018-12-22 12:01:31 -08:00
|
|
|
|
}
|
2018-12-17 22:44:06 -08:00
|
|
|
|
|
2018-12-29 12:31:27 -08:00
|
|
|
|
static func sendCrashLogText(_ crashLogText: String) {
|
2021-03-02 22:08:11 -08:00
|
|
|
|
var request = URLRequest(url: URL(string: "https://services.netnewswire.com/reportCrash.php")!)
|
2019-01-09 23:02:01 -08:00
|
|
|
|
request.httpMethod = HTTPMethod.post
|
|
|
|
|
|
|
|
|
|
let boundary = "0xKhTmLbOuNdArY"
|
|
|
|
|
|
2019-01-11 22:11:46 -08:00
|
|
|
|
let contentType = "multipart/form-data; boundary=\(boundary)"
|
2019-01-09 23:02:01 -08:00
|
|
|
|
request.setValue(contentType, forHTTPHeaderField:HTTPRequestHeader.contentType)
|
|
|
|
|
|
|
|
|
|
let formString = "--\(boundary)\r\nContent-Disposition: form-data; name=\"crashlog\"\r\n\r\n\(crashLogText)\r\n--\(boundary)--\r\n"
|
|
|
|
|
let formData = formString.data(using: .utf8, allowLossyConversion: true)
|
|
|
|
|
request.httpBody = formData
|
|
|
|
|
|
2024-06-07 22:28:24 -07:00
|
|
|
|
Task { @MainActor in
|
|
|
|
|
try? await OneShotDownloadManager.shared.download(request)
|
2019-01-11 21:59:27 -08:00
|
|
|
|
}
|
2018-12-22 12:01:31 -08:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-11 18:09:36 -06:00
|
|
|
|
static func runCrashReporterWindow(_ crashLogText: String) {
|
|
|
|
|
crashReportWindowController = CrashReportWindowController(crashLogText: crashLogText)
|
2019-01-11 22:50:36 -08:00
|
|
|
|
crashReportWindowController!.showWindow(self)
|
2018-12-17 22:44:06 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-20 22:21:42 -08:00
|
|
|
|
private extension CrashReporter {
|
2018-12-17 22:44:06 -08:00
|
|
|
|
|
2018-12-22 12:01:31 -08:00
|
|
|
|
static func shouldSendCrashLogsAutomatically() -> Bool {
|
|
|
|
|
return UserDefaults.standard.bool(forKey: DefaultsKey.sendCrashLogsAutomaticallyKey)
|
2018-12-20 22:21:42 -08:00
|
|
|
|
}
|
|
|
|
|
}
|