macOS integration guide

Add Bugsnag to your macOS projects to automatically capture and report crashes in released applications.

This documentation is for version 5 of the BugSnag macOS notifier. We recommend upgrading to the latest release using our Upgrade guide. Documentation for the current release can be found here.

Installation

Add the Bugsnag pod to your Podfile:

pod 'Bugsnag'

Don’t forget to run pod install after updating your Podfile.

Using Carthage

Add Bugsnag to your Cartfile:

github "bugsnag/bugsnag-cocoa"

Then run carthage update --platform macos to generate the frameworks to add to your project from Carthage/Build.

Manual installation

  1. Clone the BugSnag GitHub repository and its submodules into your source control environment:

    git clone --recursive https://github.com/bugsnag/bugsnag-cocoa
    cd bugsnag-cocoa && git checkout tags/<latest release>
    

    where <latest release> is the most recent release of the library

  2. Open Xcode and add Bugsnag.xcodeproj to your workspace from the folder with your platform name (iOS, OSX, or tvOS).

  3. Select your project, select your app target, and add libc++.tbd, and libz.tbd to the “Link binary with libraries” section.

  4. Add Bugsnag.framework to the “Embedded Binaries” section (which should automatically add the same entries to “Linked Frameworks and Libraries”).

  5. Add SystemConfiguration.framework to your app target under the “Linked Frameworks and Libraries” section.

Basic configuration

Import the BugSnag header in your application delegate’s implementation file:

#import <Bugsnag/Bugsnag.h>
import Bugsnag

In your application:didFinishLaunchingWithOptions: method, initialize Bugsnag:

[Bugsnag startBugsnagWithApiKey:@"your-api-key-goes-here"];
Bugsnag.start(withApiKey: "your-api-key-goes-here")

Configuring symbolication

Stacktraces from Apple platforms include backtraces with memory addresses, but symbolication is required to replace the memory addresses with human-readable function names, file paths, and line numbers. Follow the symbolication guide to configure symbolication during your build and release process.

Further configuration

If you’d like to configure Bugsnag further, check out the configuration options reference.

Reporting unhandled exceptions

Mac exceptions in the main thread are caught by cocoa and don’t reach Bugsnag by default. You should subclass NSApplication to get notifications sent to Bugsnag.

First create a new Cocoa class in your Mac project that is a subclass of NSApplication and import Bugsnag in the implementation:

#import <Bugsnag/Bugsnag.h>
import Bugsnag

Define a reportException method to notify Bugsnag of exceptions:

- (void)reportException:(NSException *)theException {
    [Bugsnag notify:theException];
    [super reportException:theException];
}
func reportException(exception: NSException) {
  Bugsnag.notify(exception)
  super.reportException(exception)
}

Finally, edit your target settings by clicking on the info tab and editing Principal class to contain your new NSApplication class name. Exceptions on your main thread will now be sent to Bugsnag.

It is worth noting that you should also use try{}catch{} blocks inside your application delegate functions and manually notify Bugsnag of any exceptions. This is another limitation of the exception handling in Mac applications that the exception handler is only guaranteed to be called after application initialization has completed.

Reporting handled exceptions

If you would like to send handled exceptions to BugSnag, you can pass any NSException object to BugSnag’s notify method:

@try {
    // Some potentially crashy code
} @catch (NSException* exception) {
    [Bugsnag notify:exception];
}
let exception = NSException(name:NSExceptionName(rawValue: "NamedException"),
                            reason:"Something happened",
                            userInfo:nil)
Bugsnag.notify(exception)

Instances of NSError can be sent using the notifyError method:

[Bugsnag notifyError:[NSError errorWithDomain:@"com.example" code:408 userInfo:nil]];
Bugsnag.notifyError(NSError(domain:"com.example", code:408, userInfo:nil))

Adding diagnostics or adjusting severity

It can often be helpful to adjust the severity or attach custom diagnostics to handled exceptions. For more information, see reporting handled errors.

Sending diagnostic data

Automatically captured diagnostics

Bugsnag will automatically capture and attach the following diagnostic data to every exception report:

  • A full stacktrace
  • Device model and OS version
  • Thread state for all threads
  • Release stage (production, debug, etc)
  • App running duration in the foreground and/or background
  • A device- and vendor-specific identifier

Attaching custom diagnostics

It can often be helpful to attach application-specific diagnostic data to exception reports. This can be accomplished as follows:

@try {
    // Some potentially crashy code
} @catch (NSException* exception) {
    [Bugsnag notify:exception withData:@{@"company": @"Acme Co."}];
}
let exception = NSException(name:"NamedException",
                            reason:"Something happened",
                            userInfo:nil)
Bugsnag.notify(exception, withData:{"company":"Acme Co."})

It is also possible to inspect and modify exception reports before they are delivered using beforeSendBlocks. See the beforeSendBlocks reference for more details.

Identifying users

In order to correlate errors with customer reports, or to see a list of users who experienced each error, it is helpful to capture and display user information.

This can be accomplished as follows:

[[Bugsnag configuration] setUser:@"userId"
                        withName:@"User Name"
                        andEmail:@"user@email.com"];
Bugsnag.configuration()?.setUser("userId", withName:"User Name",
                                           andEmail:"user@example.com")

For more information, see configuration options.

Session Tracking

BugSnag tracks the number of “sessions” that happen within your application. This allows you to compare stability scores between releases and helps you to understand the quality of your releases.

Sessions are captured and reported by default. This behavior can be disabled using the shouldAutoCaptureSessions configuration option.

BugSnag will automatically report a session each time the application enters the foreground state.

If you want control over what is deemed a session, you can switch off automatic session tracking with the shouldAutoCaptureSessions option, and manage the session lifecycle using startSession, stopSession and resumeSession.

Disabling error reporting

If you wish to disable error reporting, you can return false within a config block. This would allow for users to opt out of sending error reports, for example:

[Bugsnag.configuration addBeforeSendBlock:^bool (NSDictionary *_Nonnull rawEventData,
                                  BugsnagCrashReport *report) {
    return NO; // no error report will be sent
}];
Bugsnag.configuration()?.add(beforeSend: { (rawData, report) -> Bool in
    return false // no error report will be sent
}

Logging breadcrumbs

In order to understand what happened in your application before each crash, it can be helpful to leave short log statements that we call breadcrumbs. The last several breadcrumbs are attached to a crash to help diagnose what events lead to the error.

Automatically captured breadcrumbs

By default, BugSnag captures common events including:

  • Low memory warnings
  • Device rotation (if applicable)
  • Menu presentation
  • Screenshot capture (not the screenshot itself)
  • Undo and redo
  • Table view selection
  • Window visibility changes
  • Non-fatal errors

Attaching custom breadcrumbs

Leaving breadcrumbs can be accomplished as follows:

[Bugsnag leaveBreadcrumbWithMessage:@"Button tapped"];
Bugsnag.leaveBreadcrumb(withMessage: "Button tapped")

When logging breadcrumbs, we’ll keep track of the timestamp, and show both the message and timestamp on your dashboard.

For more information or to customize the diagnostics sent with a breadcrumb, see Customizing individual breadcrumbs.

Next steps