| Example mail composer | Example Report |
|---|---|
![]() |
![]() |
Diagnostics is a library written in Swift which makes it really easy to share Diagnostics Reports to your support team.
Features
The library allows to easily attach the Diagnostics Report as an attachment to the MFMailComposeViewController.
- Integrated with the
MFMailComposeViewController - Default reporters include:
- App metadata
- System metadata
- System logs divided per session
- Possibility to filter out sensitive data using a
DiagnosticsReportFilter - A custom
DiagnosticsLoggerto add your own logs - Agent-friendly single-file HTML reports with embedded structured JSON or standalone JSON output
- Smart insights like " ⚠️ User is low on storage" and "✅ User is using the latest app version"
- Flexible setup to add your own smart insights
- Flexible setup to add your own custom diagnostics
- Native cross-platform support, e.g. iOS, iPadOS and macOS
Usage
The default report already contains a lot of valuable information and could be enough to get you going.
Make sure to set up the DiagnosticsLogger as early as possible to catch all the system logs, for example in the didLaunchWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { do { try DiagnosticsLogger.setup() } catch { print("Failed to setup the Diagnostics Logger") } return true }
Then, simply show the MFMailComposeViewController using the following code:
import UIKit import MessageUI import Diagnostics class ViewController: UIViewController { @IBAction func sendDiagnostics(_ sender: UIButton) { Task { @MainActor in /// Create the report. let report = await DiagnosticsReporter.create() guard MFMailComposeViewController.canSendMail() else { /// For debugging purposes you can save the report to desktop when testing on the simulator. /// This allows you to iterate fast on your report. report.saveToDesktop() return } let mail = MFMailComposeViewController() mail.mailComposeDelegate = self mail.setToRecipients(["support@yourcompany.com"]) mail.setSubject("Diagnostics Report") mail.setMessageBody("An issue in the app is making me crazy, help!", isHTML: false) /// Add the Diagnostics Report as an attachment. mail.addDiagnosticReport(report) present(mail, animated: true) } } } extension ViewController: MFMailComposeViewControllerDelegate { func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { controller.dismiss(animated: true) } }
On macOS you could send the report by using the NSSharingService:
import AppKit import Diagnostics func send(report: DiagnosticsReport) { let service = NSSharingService(named: NSSharingService.Name.composeEmail)! service.recipients = ["support@yourcompany.com"] service.subject = "Diagnostics Report" let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Diagnostics-Report.html") // remove previous report try? FileManager.default.removeItem(at: url) do { try report.data.write(to: url) } catch { print("Failed with error: \(error)") } service.perform(withItems: [url]) }
Agent-friendly reports
Diagnostics reports remain a single .html attachment that users can email and open in a browser. New reports also embed a structured JSON payload in:


