Skip to content

BugSplat-Git/bugsplat-apple

Repository files navigation

bugsplat-github-banner-basic-outline

BugSplat

Crash and error reporting built for busy developers.


Introduction πŸ‘‹

The BugSplat.xcframework enables posting crash reports from iOS, macOS, and Mac Catalyst applications to BugSplat. Visit bugsplat.com for more information and to sign up for an account.

Requirements πŸ“‹

  • BugSplat for iOS supports iOS 13 and later.
  • BugSplat for macOS supports macOS 10.13 and later.

Integration πŸ—οΈ

BugSplat supports multiple methods for installing the xcfamework in a project.

Swift Package Manager (SPM)

Add the following URL to your project's Additional Package Dependencies:

https://github.com/BugSplat-Git/bugsplat-apple

Manual Setup

To manually install the xcframework in your project:

  1. Download the latest release from the Releases page. The release will contain a zip file with the xcframework.
  2. Unzip the archive.
  3. In Xcode, select your app target, then go to the General tab, scroll down to Framework, Libraries, and Embedded Content, then click the "+" and navigate to locate the unzipped BugSplat.xcframework. Once added, select Embed & Sign.

Usage πŸ§‘β€πŸ’»

Configuration

BugSplat requires a few Xcode configuration steps in order integrate the xcframework with your BugSplat account

Add the following case sensitive key to your app's Info.plist replacing DATABASE_NAME with your customer-specific BugSplat database name.

<key>BugSplatDatabase</key>
<string>DATABASE_NAME</string>

Note

For macOS apps, you must enable Outgoing network connections (client) in the Signing & Capabilities of the Target.

Symbol Upload

To symbolicate crash reports, you must upload your app's dSYM files to the BugSplat server. There are scripts to help with this.

Download BugSplat's cross-platform tool, symbol-upload-macos for Apple Silicon by entering the following command in your terminal.

curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos"

Alternatively, you can download the Intel version via the following command.

curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos-intel"

Make symbol-upload-macos executable

chmod +x symbol-upload-macos

Several options exist to integrate symbol-upload-macos into the app build process.

Note

For build-phase script to create dSYM files, change Build Settings DEBUG_INFORMATION_FORMAT from DWARF to DWARF with dSYM File. See inline notes within each script for modifications to Xcode Build Settings required for each script to work.

Please refer to our documentation to learn more about how to use symbol-upload-macos.

Initialization

Several iOS and macOS test app examples are included within the Example_Apps folder, to show how simple and quickly BugSplat can be integrated into an app, and ready to submit crash reports.

You can instantiate BugSplat by following the language specific examples below.

Swift (UIKit)

import BugSplat

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Initialize BugSplat
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()

        return true
    }
}

extension AppDelegate: BugSplatDelegate {
    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}

Swift (SwiftUI)

import BugSplat

@main
struct BugSplatTestSwiftUIApp: App {
    private let bugSplat = BugSplatInitializer()

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

@objc class BugSplatInitializer: NSObject, BugSplatDelegate {
    override init() {
        super.init()
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()
    }

    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}

Obj-C

#import "BugSplatMac/BugSplatMac.h"

@interface AppDelegate () <BugSplatDelegate>
@end

@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Initialize BugSplat
    [[BugSplat shared] setDelegate:self];
    [[BugSplat shared] setAutoSubmitCrashReport:NO];
    [[BugSplat shared] start];
}

#pragma mark - BugSplatDelegate

- (void)bugSplatWillSendCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReport called");
}

- (void)bugSplatWillSendCrashReportsAlways:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReportsAlways called");
}

- (void)bugSplatDidFinishSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatDidFinishSendingCrashReport called");
}

- (void)bugSplatWillCancelSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillCancelSendingCrashReport called");
}

- (void)bugSplatWillShowSubmitCrashReportAlert:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillShowSubmitCrashReportAlert called");
}

- (void)bugSplat:(BugSplat *)bugSplat didFailWithError:(NSError *)error {
    NSLog(@"bugSplat:didFailWithError: %@", [error localizedDescription]);
}

Crash Reporter Customization

There are several ways to customize your BugSplat crash reporter.

Custom Banner Image

  • BugSplat for macOS provides the ability to configure a custom image to be displayed in the crash reporter UI for branding purposes. The image view dimensions are 440x110 and will scale down proportionately. There are 2 ways developers can provide an image:

    1. Set the image property directly on BugSplat
    2. Provide an image named bugsplat-logo in the main app bundle or asset catalog

User Details

  • Set askUserDetails to NO in order to prevent the name and email fields from displaying in the crash reporter UI. Defaults to YES.

Auto Submit

  • By default, BugSplat will auto submit crash reports for iOS and will prompt the end user to submit a crash report for macOS. This default can be changed using a BugSplat property autoSubmitCrashReport. Set autoSubmitCrashReport to YES in order to send crash reports to the server automatically without presenting the crash reporter dialogue.

Persist User Details

  • Set persistUserDetails to YES to save and restore the user's name and email when presenting the crash reporter dialogue. Defaults to NO.

Expiration Time

  • Set expirationTimeInterval to a desired value (in seconds) whereby if the difference in time between when the crash occurred and next launch is greater than the set expiration time, auto send the report without presenting the crash reporter dialogue. Defaults to -1, which represents no expiration.

Attachments

Bugsplat supports uploading attachments with crash reports. There's a delegate method provided by BugSplatDelegate that can be implemented to provide attachments to be uploaded.

Bitcode

Bitcode was introduced by Apple to allow apps sent to the App Store to be recompiled by Apple itself and apply the latest optimization. Bitcode has now been officially deprecated by Apple and should be removed or disabled. If Bitcode is enabled, the symbols generated for your app in the store will be different than the ones from your own build system. We recommend that you disable bitcode in order for BugSplat to reliably symbolicate crash reports. Disabling bitcode significantly simplifies symbols management and currently doesn't have any known downsides for iOS apps.

Localization

For macOS, the BugSplat crash dialogue can be localized and supports 8 languages out of the box.

  1. English
  2. Finnish
  3. French
  4. German
  5. Italian
  6. Japanese
  7. Norwegian
  8. Swedish

Additional languages may be supported by adding the language bundle and strings file to BugSplat.xcframework/macos-arm64_x86_64/BugSplatMac.framework/Versions/A/Frameworks/HockeySDK.framework/Resources/

Sample Applications πŸ§‘β€πŸ«

Example_Apps includes several iOS and macOS BugSplat Test apps. Integrating BugSpat only requires the xcframework, and a few lines of code.

  1. Clone the bugsplat-apple repo.

  2. Open an example Xcode project from Example_Apps. For iOS, set the destination to be your iOS device. After running from Xcode, stop the process and relaunch from iOS device directly.

  3. Once the app launches, click the "crash" button when prompted.

  4. Relaunch the app on the iOS device. At this point a crash report should be submitted to bugsplat.com

  5. Visit BugSplat's Crashes page. When prompted for credentials enter user [email protected] and password Flintstone. The crash you posted from BugSplatTester should be at the top of the list of crashes.

  6. Click the link in the "Crash ID" column to view more details about your crash.

Contributing 🀝

BugSplat is an open source project and we welcome contributions from the community. To configure a development environment, follow the instructions below.

Prerequisites

Warning

This project requires Xcode Command Line Tools 15.x to build. Version 16.x will crash when building the project.

Install Xcode 15.4 by following this link and searching for Xcode 15.4. Download the zip file and copy Xcode.app to your Applications folder. If you already have Xcode installed create a new folder in Applications and copy Xcode.app to that folder. Rename Xcode.app to Xcode-15.4.app.

Open terminal and select the Command Line Tools for Xcode 15.4

sudo xcode-select -s /Applications/Xcodes/Xcode-15.4.app

Building

Clone this repository and all of the depenencies into a new BugSplat folder.

mkdir BugSplat
cd BugSplat
git clone https://github.com/BugSplat-Git/bugsplat-apple
git clone https://github.com/BugSplat-Git/HockeySDK-Mac
git clone https://github.com/BugSplat-Git/HockeySDK-iOS
git clone https://github.com/BugSplat-Git/plCrashReporter

Next, in the prescribed order, build each repo. If an error occurs in a specific repo, it must be resolved before you can move to the next repo. This process was verified with specific Apple Developer account for code signing. A different Apple Developer account require adjusting the code signing within a given project.

  1. Build PlCrashReporter
cd plcrashreporter
./makeXCFramework.sh
...
xcframework successfully written out to: .../BugSplat/plcrashreporter/xcframeworks/CrashReporter.xcframework
  1. Build HockeySDK-Mac
cd HockeySDK-Mac
./makeXCFramework.sh
...
xcframework successfully written out to: .../BugSplat/HockeySDK-Mac/xcframeworks/HockeySDK-macOS.xcframework
  1. Build HockeySDK-iOS
cd HockeySDK-iOS
./makeXCFramework.sh
...
xcframework successfully written out to: .../BugSplat/HockeySDK-iOS/xcframeworks/HockeySDK.xcframework
  1. Build bugsplat-apple
cd bugsplat-apple
./makeXCFramework.sh
...
xcframework successfully written out to: .../BugSplat/bugsplat-apple/xcframeworks/BugSplat.xcframework

If all goes smoothly, BugSplat.xcframework will be the result in the xcframeworks folder of the bugsplat-apple repo.

Releasing

To release a new version of BugSplat.xcframework, push a new tag to the main branch. The release workflow will build the xcframework, update Package.swift, and publish the zipped archive to the Releases page.