Skip to content

Honeybadger for iOS, macOS, and visionOS

View Markdown

Typical installation time: ~5 minutes

Hi there! You’ve found Honeybadger’s guide to Cocoa exception and error tracking for iOS, macOS, and visionOS. Once installed, Honeybadger will automatically report crashes and errors in your app.

Version 2.x of the SDK requires:

  • iOS 16.0+
  • macOS 13.0+
  • visionOS 1.0+

If you need to support earlier OS versions, use the 1.x release of the SDK, which supports iOS 13.0+ and macOS 10.15+.

To install via CocoaPods, create/open your Podfile and add a pod entry for ‘Honeybadger’. Make sure use_frameworks! is specified.

Terminal window
use_frameworks!
target 'MyApp' do
pod 'Honeybadger'
end

Open your app in Xcode, then go to File > Add Package Dependencies, and specify the Honeybadger Cocoa GitHub repo: https://github.com/honeybadger-io/honeybadger-cocoa

You will need your Honeybadger API key to initialize the Honeybadger library. You can log into your Honeybadger account to obtain your API key.

In your App Delegate, import the Honeybadger library:

import Honeybadger

In your didFinishLaunchingWithOptions method, add the following code to initialize Honeybadger:

Honeybadger.configure(apiKey:"PROJECT_API_KEY")

You can also configure Honeybadger with an optional custom environment parameter:

Honeybadger.configure(
apiKey:"PROJECT_API_KEY",
environment:"staging"
)

You can also supply an optional revision to track which release an error came from (e.g. a version string, build number, or git SHA). If you upload dSYMs for crash symbolication, use the same revision value there, so dSYMs and the errors they symbolicate are tagged with the same release:

Honeybadger.configure(
apiKey:"PROJECT_API_KEY",
environment:"production",
revision:"1.4.2"
)

Finally, if your Honeybadger account is in our EU region, or you route requests through a proxy, pass a custom endpoint — the base URL of the Honeybadger API (scheme and host, with an optional path prefix). When omitted, the SDK reports to https://api.honeybadger.io. The endpoint can be combined with the environment and revision parameters:

Honeybadger.configure(
apiKey:"PROJECT_API_KEY",
endpoint:"https://eu-api.honeybadger.io"
)

The endpoint only applies to error reports sent by the SDK; dSYM uploads are configured separately, in the build phase that runs the upload script.

Once configured, the SDK reports the following without any additional code:

  • Uncaught exceptions — unhandled NSExceptions that terminate the app.
  • Fatal signals — SIGABRT, SIGSEGV, SIGBUS, SIGFPE, SIGILL, and SIGTRAP. Signal handlers run on a dedicated alternate stack, so stack-overflow crashes are captured too.
  • AppKit event-loop exceptions (macOS) — exceptions thrown inside AppKit event handlers (e.g. button actions) are caught by AppKit’s own event loop and never reach the uncaught-exception handler; the SDK hooks -[NSApplication reportException:] to capture them. The SDK also registers NSApplicationCrashOnExceptions = YES as a default, so the app terminates after the crash is recorded rather than continuing in an undefined state. This is a change from 1.x, where such exceptions were not captured and the app kept running. To keep the old behavior, set NSApplicationCrashOnExceptions to NO in your app’s user defaults; an explicit value set by your app always wins.

Call configure as early as possible in your app’s launch. Stack-overflow crashes can only be captured on the thread that calls configure and on threads created after it; threads already running at that point can’t be given an alternate signal stack.

Crash reports are persisted to disk at crash time and delivered to Honeybadger on the next launch if the process terminates before the report can be sent, so crashes aren’t lost.

If another crash reporter is already installed, the SDK chains to it: any previously installed exception or signal handlers are saved and invoked after Honeybadger records the crash.

Crash reports from production builds contain raw memory addresses rather than function names and line numbers. To get readable stack traces, see Symbolicating crash reports with dSYMs.

In addition to automatic crash reporting, you can use the following API to customize error handling in your application.

You can use the notify methods to manually send an error as a string or Error/NSError object. If available, the Honeybadger library will attempt to extract a stack trace and any relevant information that might be useful.

The notify methods accept several optional parameters, which can be combined:

  • context — a dictionary of data to include with the error (e.g. a user ID).
  • errorClass — a custom class name for the error, used in place of the default.
  • fingerprint — a custom fingerprint for error grouping.
Honeybadger.notify(
errorString: "My error"
);
Honeybadger.notify(
errorString: "My error",
context: ["user_id" : "123abc"]
);
Honeybadger.notify(
errorString: "My error",
errorClass: "MyCustomErrorType"
);
Honeybadger.notify(
errorString: "My error",
fingerprint: "my-custom-error-fingerprint"
);
// ---
Honeybadger.notify(
error: MyError("This is my custom error.")
);
Honeybadger.notify(
error: MyError("This is my custom error."),
errorClass: "MyCustomErrorType",
context: ["user_id" : "123abc"],
fingerprint: "my-custom-error-fingerprint"
);

If you have data that you would like to include whenever an error or an exception occurs, you can provide that data using the setContext method. You can call setContext as many times as needed. New context data will be merged with any previously-set context data.

Honeybadger.setContext(context: ["user_id" : "123abc"]);

If you’ve used setContext to store data, you can use resetContext to clear that data.

Honeybadger.resetContext();

Note: in versions before 2.0.0, resetContext took a dictionary argument that replaced the stored context. As of 2.0.0 it takes no arguments and clears the context; to replace context, call resetContext followed by setContext.

Also as of 2.0.0, the SDK no longer collects or sends the device hostname (server.hostname). Looking it up could trigger the macOS local-network permission prompt and block for several seconds, and a device hostname is personally identifying. If you want a host identifier on your reports, add one with setContext.