Raygun4Apple - Error & Crash Reporting

Raygun crash reporting and error monitoring is available for iOStvOS & macOS with the raygun4apple provider. This provider can be used with both Objective-C and Swift applications.

Setup instructions

1. Install the Raygun4Apple package

Download the latest package installer from here. Run the installer and follow the on-screen instructions.

2. Reference Raygun4Apple in your project

To use the framework in an app project, you will need to first select the Project in the Project Navigator. Then select the Target for the Project and scroll down to the Embedded Binaries section.

Next, in Finder, open the Library > Frameworks > raygun4apple directory. Open the folder corresponding to the platform your Target is currently supporting. Select the raygun4apple.framework file and drag it into the Embedded Binaries section.

3. Add the import dependency

For Swift projects you must create an Objective-C bridging header to be able to import the provider's umbrella header file. You can find out how to do this by visiting Apple's documentation for more details.

In your AppDelegate's source file or Objective-C bridging header file, import the umbrella header for your target platform.

For iOS: 

#import <raygun4apple/raygun4apple_iOS.h>

For tvOS: 

#import <raygun4apple/raygun4apple_tvOS.h>

For macOS:

#import <raygun4apple/raygun4apple_macOS.h>

4. Start the Raygun crash reporter

In your AppDelegate's application function, add the following code to start the Raygun crash reporter. Your app API key is displayed when you create a new application in your Raygun account, or can be viewed in the application settings.


RaygunClient *raygunClient = [RaygunClient sharedInstanceWithApiKey:@"YOUR_APP_API_KEY"];
[raygunClient enableCrashReporting];


let raygunClient = RaygunClient.sharedInstance(apiKey: "YOUR_APP_API_KEY")

Modify or cancel messages

The provider allows you the chance to inspect the reports before they are sent to Raygun servers. You can inspect and modify the report details or cancel the report from being sent altogether. This is done by setting a block on the shared Raygun client and will be called just before a report is sent - either automatically or manually. 


RaygunClient.sharedInstance.beforeSendMessage = ^BOOL(RaygunMessage * _Nonnull message) {
    if ([message.details.machineName isEqualToString:@"LOCAL_MACBOOK"]) {
      return NO; // Don't send the report

    // Remove user information
    message.details.user = nil;

    return YES;


RaygunClient.sharedInstance().beforeSendMessage = { (message) in
    if (message.details.error.className == "NotImplementedException") {
      return false // Don't send the report

    // Remove user information
    message.getails.user = nil

    return true

Unique user tracking

This provider supports tracking the unique users who encounter errors and crashes in your mobile apps.

The identifier property on the RaygunUserInformation class is what separates one user from another. Be sure to set it with something unique, for example a database id, username or email address.

If the user changes, for instance when logging in or out, be sure to update the user information on the shared Raygun client each time. You can assign user information as described below.


RaygunUserInformation *userInfo = [[RaygunUserInformation alloc] initWithIdentifier:@""
                                                                       withFullName:@"Test User"
RaygunClient.sharedInstance.userInformation = userInfo;


let userInformation = RaygunUserInformation(identifier: "", email: "", fullName: "Test User", firstName: "Test")
RaygunClient.sharedInstance().userInformation = userInformation


With breadcrumbs, you can attach an accurate trail of events through your system leading up to the moment a report was generated. This helps to gain more insight into why the application crashed when it did, making prioritization of fixes much easier.

The easiest way to record a breadcrumb is by calling the recordBreadcrumb:withCategory:withLevel:withCustomData method on the RaygunClient instance. An example would be as described below.


[RaygunClient.sharedInstance recordBreadcrumbWithMessage:@"User authentication succeeded" 
                                          withCustomData:@{ @"UserId": @123456 }];


RaygunClient.sharedInstance().recordBreadcrumb(message: "User authetication succeeded", category: "Login", level:, customData: ["UserId": 123456])

You can also construct your own RaygunBreadcrumb object and record it by passing it to the RaygunClient instance.


RaygunBreadcrumb *breadcrumb = [RaygunBreadcrumb breadcrumbWithBlock:^(RaygunBreadcrumb *crumb) {
    crumb.message    = @"User authentication succeeded";
    crumb.category   = @"Login";
    crumb.level      = RaygunBreadcrumbLevelInfo;
    crumb.className  = @"loginAuthentication";
    crumb.methodName = @"authenticate";
    crumb.lineNumber = @123;
    crumb.customData = @{ @"UserId": @123456 };

[RaygunClient.sharedInstance recordBreadcrumb:breadcrumb];


let breadcrumb = RaygunBreadcrumb { (crumb) in
    crumb.message    = "User authentication succeeded"
    crumb.category   = "Login"
    crumb.level      =
    crumb.className  = "loginAuthentication"
    crumb.methodName = "authenticate"
    crumb.lineNumber = 123
    crumb.customData = ["UserId": @123456]

RaygunClient.sharedInstance().record(breadcrumb: breadcrumb)


An array of strings can be sent with each report and displayed in Raygun. This can be used to categorise errors or add additional contextual information. These tag values are also searchable in your Raygun dashboard so that you can find all error instances that you've marked with a particular tag.

Global tags

Sometimes you may want tags to be sent with all errors regardless of if they are manually or automatically reported. This can be done by setting the tags property on the shared Raygun client as described below.


RaygunClient.sharedInstance.tags = @[@"GlobalTag1", @"GlobalTag2"];


RaygunClient.sharedInstance().tags = ["GlobalTag1", "GlobalTag2"]

Per error tags

When manually reporting errors to Raygun, you can include an array of tags that will appear on that report only. 


NSException *exception = [NSException exceptionWithName:@"TestException" reason:@"Something went wrong" userInfo:nil];
[RaygunClient.sharedInstance sendException:exception withTags:@[@"CustomTag1", @"CustomTag2"]];


let exception = NSException(name: NSExceptionName.genericException, reason "Something went wrong")
RaygunClient.sharedInstance().send(exception: exception, tags: ["CustomTag1", "CustomTag2"])

Custom data

Each error can be reported with a dictionary of custom data. This data gets displayed in Raygun and can be used to record useful contextual information for debugging. Please note: currently the custom data dictionary should only include simple values such as strings and numbers.

Global custom data


RaygunClient.sharedInstance.customData = @{ @"GlobalMessage" : @"Hello world", @"GlobalId" : @123 };


RaygunClient.sharedInstance().customData = ["GlobalMessage": "Hello world", "GlobalId": 123]

Per error custom data

When manually reporting errors to Raygun, you can include a dictionary of custom data that will appear on that report only. Below is an example of how to do this. The tags array can be nil if you don't have any tags for this error.


NSException *exception = [NSException exceptionWithName:@"TestException" reason:@"Something went wrong" userInfo:nil];
[RaygunClient.sharedInstance sendException:exception withTags:nil withCustomData:@{ @"CustomMessage" : @"It was me!", @"CustomMagicNumber" : @21 }];


let exception = NSException(name: NSExceptionName.genericException, reason "Something went wrong")
RaygunClient.sharedInstance().send(exception: exception, tags: nil, customData: ["CustomMessage": "It was me!", "CustomMagicNumber": 21])

Internal logging

For debugging purposes you can set the level of logging that the provider will print to your debug console. This can be helpful to determine what information is or is not being sent to the Raygun API. The logging level can be set anytime, even before initialising the Raygun client.


RaygunClient.logLevel = RaygunLoggingLevelVerbose;


RaygunClient.logLevel = RaygunLoggingLevel.verbose


This provider transmits encoded reports it receives from your app as it runs on devices or emulators. To turn these reports into useful data that you can use to debug, Raygun requires your app's dSYM file. This is generated on build in Xcode and is unique to every version of your app's source. When you are finished testing locally and are deploying a new build, you need to upload the new dSYM file corresponding to that build.

Once Raygun has that build's dSYM file, the encoded reports will be turned into complete back traces, with line numbers and file names.

Uploading a dSYM file

Here are 3 options for uploading your dSYM files to your Raygun account:

1. Raygun Sidekick - dSYM uploader macOS app

The Raygun Sidekick is a native Mac application that sits in your Mac menu bar which will detect, zip and upload the appropriate dSYM file in just a few clicks. It is highly recommend that you use the Raygun Sidekick rather than tediously uploading the dSYM files yourself as described below.

Download the Raygun Sidekick right here and check out the documentation for more info.

2. Manual upload

To manually upload dSYM files, visit the Raygun dashboard, click on dSYM Center in the sidebar, then upload the dSYM file by drag 'n dropping or using Finder.

You can do this at any time. If you deploy a new build and Raygun receives reports without the dSYM file, it will store them ready for you to upload it. When you do, visit a report from that build and click on 'Reprocess crash report'. After a short delay, the stack trace will appear.

3. Automated uploading via cURL

For sending dSYMs to Raygun in other processes such as build scripts or the terminal, you can post via cURL. Below are examples of uploading a dSYM file using cURL with different authentication methods. Each <variable> needs to be substituted (including the angle brackets) with your own value as described below each code example.

  1. By external access token

    curl -F "DsymFile=@<PATH_TO_DSYM_ZIP>"<RAYGUN_APPLICATION_ID>/settings/symbols?authToken=<EXTERNAL_ACCESS_TOKEN>

    <PATH_TO_DSYM_ZIP> is an absolute or relative path to a zip of you dSYM file including the file name and .zip extension.
    <RAYGUN_APPLICATION_ID> is available in the URL of your Raygun application dashboard.
    <EXTERNAL_ACCESS_TOKEN> can be obtained from Raygun by clicking your name in the top right corner, select "My settings" and then hit "Generate external access token" or copy it if you already have one.

  2. By basic authentication

    curl -H "Authorization: Basic <BASIC_AUTH_TOKEN>" -F "DsymFile=@<PATH_TO_DSYM_ZIP>"<RAYGUN_APPLICATION_ID>/settings/symbols

    <BASIC_AUTH_TOKEN> can be generated by taking your Raygun account credentials in the format username:password and then using the base 64 result.
    <PATH_TO_DSYM_ZIP> is an absolute or relative path to a zip of you dSYM file including the file name and .zip extension.
    <RAYGUN_APPLICATION_ID> is available in the URL of your Raygun application dashboard.

  3. By username and password

    curl -u <USERNAME>:<PASSWORD> -F "DsymFile=@<PATH_TO_DSYM_ZIP>"<RAYGUN_APPLICATION_ID>/settings/symbols

    <USERNAME> and <PASSWORD> are your Raygun account credentials.
    <PATH_TO_DSYM_ZIP> is an absolute or relative path to a zip of you dSYM file including the file name and .zip extension.
    <RAYGUN_APPLICATION_ID> is available in the URL of your Raygun application dashboard.

Make sure to include the @ before the dSYM file path which tells cURL that the file itself is to be sent, rather than sending the path string. Missing the @ will result in an Invalid dSYM file response.

Documentation missing?

If we don't have documentation about your desired topic, send us a message and we'll create it for you.