We are excited to announce a new library from Point-Free: Issue Reporting. This library provides tools to report issues in your application and library code as Xcode runtime warnings, breakpoints, assertions, and do so in a testable manner.
The primary tool for reporting an issue in your application code is the reportIssue
function. You can invoke it from anywhere in your features’ code to signal that something happened that should not have:
guard let lastItem = items.last
else {
reportIssue("'items' should never be empty.")
return
}
…
By default, this will trigger an unobtrusive, purple runtime warning when running your app in Xcode (simulator and device):
‘items’ should never be empty.
This provides a very visual way to see when an issue has occurred in your application without stopping the app’s execution or interrupting your workflow.
The reportIssue
tool can also be customized to allow for other ways of reporting issues. It can be configured to trigger a breakpoint if you want to do some debugging when an issue is reported, or a precondition or fatal error if you want to truly stop execution. And you can create your own custom issue reporter to send issues to OSLog or an external server.
Further, when running your code in a testing context (both XCTest and Swift’s native Testing framework), all reported issues become test failures:
Expectation failed: ‘items’ should never be empty.
This helps you get test coverage that problematic code paths are not executed, and makes it possible to build testing tools for libraries that ship in the same target as the library itself.
The library comes with a variety of issue reporters that can be used right away:
runtimeWarning
: Issues are reported as purple runtime warnings in Xcode and printed to the console on all other platforms. This is the default reporter.breakpoint
: A breakpoint is triggered, stopping execution of your app. This gives you the ability to debug the issue.fatalError
: A fatal error is raised and execution of your app is permanently stopped.
You an also create your own custom issue reporter by defining a type that conforms to the IssueReporter
protocol. It has one requirement, which you can implement to report issues in any way you want.
By default the library uses the runtimeWarning
reporter, but it is possible to override the reporters used. There are two primary ways:
You can temporarily override reporters for a lexical scope using
withIssueReporters
. For example, to turn off reporting entirely you can do:withIssueReporters([]) { // Any issues raised here will not be reported. }
…or to temporarily add a new issue reporter:
withIssueReporters(IssueReporters.current + [.breakpoint]) { // Any issues reported here will trigger a breakpoint }
You can also override the issue reporters globally by setting the
IssueReporters.current
variable. This is typically best done at the entry point of your application:import IssueReporting import SwiftUI @main struct MyApp: App { init() { IssueReporters.current = [.fatalError] } var body: some Scene { … } }
Add Issue Reporting to your project today to start reporting issues in an unobtrusive and testable manner. If you were previously using our XCTest Dynamic Overlay library, then you should know that Issue Reporting is the successor to that library, and you should be able to seamlessly migrate over.