诊断 1.10.0

诊断 1.10.0

Antoine v.d. Lee维护。



诊断 1.10.0

示例邮件生成器 示例报告

诊断是一个用Swift编写的库,它可以使将诊断报告分享给您的支持团队变得非常容易。

特性

此库允许轻松地将诊断报告附加为附件到MFMailComposeViewController

  • 集成MFMailComposeViewController
  • 默认报告包括
    • 应用程序元数据
    • 系统元数据
    • 按会话分的系统日志
    • 用户默认值
  • 使用DiagnosticsReportFilter过滤敏感数据
  • 自定义DiagnosticsLogger添加您自己的日志
  • 灵活配置以添加您自己的自定义诊断
  • 原生跨平台支持,例如iOS、iPadOS和macOS

使用方法

默认报告已包含大量有价值的信息,可能足以让您开始。

请尽早设置DiagnosticsLogger以捕获所有系统日志,例如在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
}

然后,只需使用以下代码显示MFMailComposeViewController

import UIKit
import MessageUI
import Diagnostics

class ViewController: UIViewController {

    @IBAction func sendDiagnostics(_ sender: UIButton) {
        /// Create the report.
        let report = 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(["[email protected]"])
        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)
    }
}

在macOS上,您可以使用NSSharingService发送报告。

import AppKit
import Diagnostics

func send(report: DiagnosticsReport) {
    let service = NSSharingService(named: NSSharingService.Name.composeEmail)!
    service.recipients = ["[email protected]"]
    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])
}

使用自定义UserDefaults类型

只需设置用户默认值实例,利用

UserDefaultsReporter.userDefaults = ..

移除敏感数据

如果报告包含敏感数据,您可以创建一个DiagnosticsReportFilter来过滤这些数据。

示例项目包含了一个该功能的示例

struct DiagnosticsDictionaryFilter: DiagnosticsReportFilter {

    // This demonstrates how a filter can be used to filter out sensible data.
    static func filter(_ diagnostics: Diagnostics) -> Diagnostics {
        guard let dictionary = diagnostics as? [String: Any] else { return diagnostics }
        return dictionary.filter { keyValue -> Bool in
            if keyValue.key == "App Display Name" {
                // Filter out the key with the value "App Display Name"
                return false
            } else if keyValue.key == "AppleLanguages" {
                // Filter out a user defaults key.
                return false
            }
            return true
        }
    }
}

这可以通过将过滤器传递给create(..)方法来使用

let report = DiagnosticsReporter.create(using: reporters, filters: [DiagnosticsDictionaryFilter.self])

添加自定义日志

要在日志诊断中显示您自己的日志,您需要使用DiagnosticsLogger

/// Support logging simple `String` messages.
DiagnosticsLogger.log(message: "Application started")

/// Support logging `Error` types.
DiagnosticsLogger.log(error: ExampleError.missingData)

错误记录器将使用本地化描述,如果有的话,您可以通过使错误符合LocalizedError来添加这些描述。

添加自定义报告

要添加自己的报告,您需要使用DiagnosticsReporting协议。

/// An example Custom Reporter.
struct CustomReporter: DiagnosticsReporting {
    static func report() -> DiagnosticsChapter {
        let diagnostics: [String: String] = [
            "Logged In": Session.isLoggedIn.description
        ]

        return DiagnosticsChapter(title: "My custom report", diagnostics: diagnostics)
    }
}

然后,您可以将其添加到创建方法中

var reporters = DiagnosticsReporter.DefaultReporter.allReporters
reporters.insert(CustomReporter.self, at: 1)
let report = DiagnosticsReporter.create(using: reporters)

为您的报告创建自定义HTML格式化器

您可以使用HTMLFormatting协议来自定义HTML报告的方式。

只需将格式化器传递给DiagnosticsChapter初始化器

DiagnosticsChapter(title: "UserDefaults", diagnostics: userDefaults, formatter: <#HTMLFormatting.Type#>)

通信

  • 如果您找到了一个错误,请提交一个问题。
  • 如果您有一个功能请求,请提交一个问题。
  • 如果您想贡献,提交一个拉取请求。

安装

Swift Package Manager

Swift Package Manager 是一个用于管理 Swift 代码分发的工具。它与 Swift 构建系统集成,使得下载、编译和链接依赖项的过程自动化。

清单文件

将诊断作为包添加到您的 Package.swift 文件中, puis 指定要使用的 Target 的依赖项。

import PackageDescription

let package = Package(
    name: "MyProject",
    platforms: [
       .macOS(.v10_15)
    ],
    dependencies: [
        .package(url: "https://github.com/WeTransfer/Diagnostics.git", .upToNextMajor(from: "1.8.0"))
    ],
    targets: [
        .target(
            name: "MyProject",
            dependencies: ["Diagnostics"]),
        .testTarget(
            name: "MyProjectTests",
            dependencies: ["MyProject"]),
    ]
)

Xcode

要将诊断添加为 依赖项 到您的 Xcode 项目中,选择 文件 > Swift Packages > 添加 Package Dependency 并输入仓库 URL: https://github.com/WeTransfer/Diagnostics.git

CocoaPods

CocoaPods 是 Cocoa 项目的依赖项管理器。您可以使用以下命令安装它

$ gem install cocoapods

要使用 CocoaPods 将诊断集成到您的 Xcode 项目中,在 Podfile 中指定它

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Diagnostics', '~> 1.0.0'
end

然后,运行以下命令

$ pod install

Carthage

Carthage 是一个分布式的依赖管理器,它可以编译你的依赖并为你提供二进制框架。

您可以使用以下命令通过 Homebrew 来安装 Carthage

$ brew update
$ brew install carthage

要使用 Carthage 将诊断工具集成到您的 Xcode 项目中,请在您的 Cartfile 中指定它

github "WeTransfer/Diagnostics" ~> 1.00

运行 carthage update 来构建框架,并将构建的 Diagnostics.framework 拖拽到您的 Xcode 项目中。

手动

如果您不希望使用上述任何依赖管理器,您可以手动集成诊断工具到您的项目中。

内嵌框架

  • 打开终端,切换到您的顶层项目目录,并运行以下命令(如果您尚未将项目初始化为 Git 仓库)

    $ git init
  • 通过以下命令将诊断工具添加为 git 子模块

    $ git submodule add https://github.com/WeTransfer/Diagnostics.git
  • 打开新的 Diagnostics 文件夹,并将 Diagnostics.xcodeproj 拖拽到 application Xcode 项目的项目导航器中。

    它应该嵌套在您 application 的蓝色项目图标下。它位于所有其他 Xcode 组之上或之下无关紧要。

  • 在项目导航器中选中 Diagnostics.xcodeproj,并验证部署目标是否与 application 目标相同。

  • 接下来,在项目导航器中选中您的 application 项目(蓝色项目图标),导航到目标配置窗口,并在侧边栏的 "Targets" 标题下选择 application 目标。

  • 在窗口顶部的标签栏中,打开 "General" 面板。

  • 点击 "Embedded Binaries" 部分的 + 按钮添加。

  • 选择 Diagnostics.framework

  • 就这么多!

    Diagnostics.framework 将自动添加为目标依赖,在 copy files 构建阶段链接为框架并内嵌,这正好满足在模拟器和设备上构建的需求。


发布说明

查看更改列表,请参阅 CHANGELOG.md

作者

该库作为 WeTransfer黑客松的一部分创建。相关进程已在 Twitter 上报道。

感谢

此外,我们对 1Password 表示赞扬,其 启发 我们创建了此库。

许可证

Diagnostics 根据 MIT 许可证提供。有关更多信息,请参阅 LICENSE 文件。