Swiftpack.co - Package - backtrace-labs/backtrace-cocoa

Backtrace

Backtrace's integration with iOS, macOS and tvOS applications allows customers to capture and report handled and unhandled exceptions to their Backtrace instance, instantly offering the ability to prioritise and debug software errors.

Supported platforms Supported languages CocoaPods compatible License: MIT

Minimal usage

Create the BacktraceClient using init(credentials:) initializer and then send error/exception just by calling method send:

  • Swift
import UIKit
import Backtrace

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://backtrace.io")!,
                                                        token: "token")
        BacktraceClient.shared = try? BacktraceClient(credentials: backtraceCredentials)

        do {
            try throwingFunc()
        } catch {
            BacktraceClient.shared?.send { (result) in
                print(result)
            }
        }

        return true
    }
}
  • Objective-C
#import "AppDelegate.h"
@import Backtrace;

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
                                         initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
                                         token: @"token"];
    BacktraceClient.shared = [[BacktraceClient alloc] initWithCredentials: credentials error: nil];

    // sending NSException
    @try {
        NSArray *array = @[];
        NSObject *object = array[1]; // will throw exception
    } @catch (NSException *exception) {
        [[BacktraceClient shared] sendWithException: exception completion:^(BacktraceResult * _Nonnull result) {
            NSLog(@"%@", result);
        }];
    } @finally {

    }

    return YES;
}

@end

Table of contents

  1. Features Summary
  2. Installation
  3. Documentation
    1. Initialize client
    2. Configure client
    3. Events handling
    4. Attributes
    5. Attachments
    6. Sending reports
      1. Error/NSError
      2. NSException
      3. macOS note
  4. FAQ
    1. Missing dSYM files

Features Summary

  • Light-weight client library written in Swift with full Objective-C support that quickly submits exceptions/errors and crashes to your Backtrace dashboard includes:
    • system metadata,
    • machine metadata,
    • signal metadata,
    • exception metadata,
    • thread metadata,
    • process metadata.
  • Supports iOS, macOS and tvOS platforms.
  • Swift first protocol-oriented framework.

Installation

via CocoaPods

To use CocoaPods just add this to your Podfile:

pod 'Backtrace'

Note: It is required to specify use_frameworks! in your Podfile.

Documentation

Initialize Backtrace client

Initializing Backtrace client requires registration to Backtrace services. You can register to Backtrace services using provided submission url (see: What is a submission url?) and token (see: What is a submission token?). These credentials you can supply using BacktraceCredentials.

  • Swift
BacktraceClient.shared = try? BacktraceClient(credentials: BacktraceCredentials)
  • Objective-C
BacktraceClient.shared = [[BacktraceClient alloc] initWithCredentials: BacktraceCredentials error: error];

Configure Backtrace client

For more advanced usage of BacktraceClient, you can supply BacktraceClientConfiguration as a parameter. See the following example:

  • Swift
let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://backtrace.io")!, token: "token")
let configuration = BacktraceClientConfiguration(credentials: backtraceCredentials,
                                                 dbSettings: BacktraceDatabaseSettings(),
                                                 reportsPerMin: 10,
                                                 allowsAttachingDebugger: false)
BacktraceClient.shared = try? BacktraceClient(configuration: configuration)
  • Objective-C
BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
                                     initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
                                     token: @"token"];

BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration alloc]
                                               initWithCredentials: credentials
                                               dbSettings: [[BacktraceDatabaseSettings alloc] init]
                                               reportsPerMin: 3
                                               allowsAttachingDebugger: NO];

BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil];

Note: Backtrace library will not send any reports if the allowsAttachingDebugger flag is set to false.

Database settings

BacktraceClient allows you to customize the initialization of BacktraceDatabase for local storage of error reports by supplying a BacktraceDatabaseSettings parameter, as follows:

  • Swift
let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://backtrace.io")!, token: "token")
let backtraceDatabaseSettings = BacktraceDatabaseSettings()
backtraceDatabaseSettings.maxRecordCount = 1000
backtraceDatabaseSettings.maxDatabaseSize = 10
backtraceDatabaseSettings.retryInterval = 5
backtraceDatabaseSettings.retryLimit = 3
backtraceDatabaseSettings.retryBehaviour = RetryBehaviour.interval
backtraceDatabaseSettings.retryOrder = RetryOder.queue
let backtraceConfiguration = BacktraceClientConfiguration(credentials: backtraceCredentials,
                                                          dbSettings: backtraceDatabaseSettings,
                                                          reportsPerMin: 10)
BacktraceClient.shared = try? BacktraceClient(configuration: backtraceConfiguration)
  • Objective-C
BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
                                     initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
                                     token: @"token"];

BacktraceDatabaseSettings *backtraceDatabaseSettings = [[BacktraceDatabaseSettings alloc] init];
backtraceDatabaseSettings.maxRecordCount = 1000;
backtraceDatabaseSettings.maxDatabaseSize = 10;
backtraceDatabaseSettings.retryInterval = 5;
backtraceDatabaseSettings.retryLimit = 3;
backtraceDatabaseSettings.retryBehaviour = RetryBehaviourInterval;
backtraceDatabaseSettings.retryOrder = RetryOderStack;

BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration alloc]
                                               initWithCredentials: credentials
                                               dbSettings: backtraceDatabaseSettings
                                               reportsPerMin: 3
                                               allowsAttachingDebugger: NO];

BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil];

Events handling

BacktraceClient allows you to subscribe for events produced before and after sending each report. You have to only attach object which confirm to BacktraceClientDelegate protocol.

  • Swift
// assign `self` or any other object as a `BacktraceClientDelegate`
BacktraceClient.shared?.delegate = self

// handle events
func willSend(_ report: BacktraceCrashReport) -> (BacktraceCrashReport)
func willSendRequest(_ request: URLRequest) -> URLRequest
func serverDidFail(_ error: Error)
func serverDidResponse(_ result: BacktraceResult)
func didReachLimit(_ result: BacktraceResult)
  • Objective-C
// assign `self` or any other object as a `BacktraceClientDelegate`
BacktraceClient.shared.delegate = self;

//handle events
- (BacktraceReport *)willSend:(BacktraceReport *)report;
- (void)serverDidFail:(NSError *)error;
- (void)serverDidResponse:(BacktraceResult *)result;
- (NSURLRequest *)willSendRequest:(NSURLRequest *)request;
- (void)didReachLimit:(BacktraceResult *)result;

Attaching BacktraceClientDelegate allows you to e.g. modify report before send:

  • Swift
func willSend(_ report: BacktraceReport) -> (BacktraceReport) {
    report.attributes["added"] = "just before send"
    return report
}
  • Objctive-C
- (BacktraceReport *)willSend:(BacktraceReport *)report {
    NSMutableDictionary *dict = [report.attributes mutableCopy];
    [dict setObject: @"just before send" forKey: @"added"];
    report.attributes = dict;
    return report;
}

Attributes

You can add custom attributes that should be send alongside crash and errors/exceptions:

  • Swift
BacktraceClient.shared?.attributes = ["foo": "bar", "testing": true]
  • Objective-C
BacktraceClient.shared.attributes = @{@"foo": @"bar", @"testing": YES};

Set attributes are attached to each report. You can specify unique set of attributes for specific report in willSend(_:) method of BacktraceClientDelegate. See events handling for more information.

Attachments

For each report you can attach files by supplying an array of file paths.

  • Swift
let filePath = Bundle.main.path(forResource: "test", ofType: "txt")!
BacktraceClient.shared?.send(attachmentPaths: [filePath]) { (result) in
    print(result)
}
  • Objectice-C
NSArray *paths = @[[[NSBundle mainBundle] pathForResource: @"test" ofType: @"txt"]];
[[BacktraceClient shared] sendWithAttachmentPaths:paths completion:^(BacktraceResult * _Nonnull result) {
    NSLog(@"%@", result);
}];

Supplied files are attached for each report. You can specify unique set of files for specific report in willSend(_:) method of BacktraceClientDelegate. See events handling for more information.

Sending an error report

Registered BacktraceClient will be able to send a crash reports. Error report is automatically generated based.

Sending Error/NSError

  • Swift
@objc func send(completion: ((BacktraceResult) -> Void))
  • Objective-C
 - (void) sendWithCompletion: (void (^)(BacktraceResult * _Nonnull)) completion;

Sending NSException

  • Swift
@objc func send(exception: NSException, completion: ((BacktraceResult) -> Void))
  • Objective-C
 - (void) sendWithException: NSException completion: (void (^)(BacktraceResult * _Nonnull)) completion;

macOS note

If you want to catch additional exceptions on macOS which are not forwarded by macOS runtime, set NSPrincipalClass to Backtrace.BacktraceCrashExceptionApplication in your Info.plist.

Alternatively, you can set:

  • Swift
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
  • Objective-C
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @YES }];

but it crashes your app if you don't use @try ... @catch.

FAQ

Missing dSYM files

Make sure your project is configured to generate the debug symbols:

  • Go to your project target's build settings: YourTarget -> Build Settings.
  • Search for Debug Information Format.
  • Select DWARF with dSYM File. alt text

Finding dSYMs while building project

  • Build the project.
  • Build products and dSYMs are placed into the Products directory. alt text alt text
  • Zip all the dSYM files and upload to Backtrace services (see: Symbolification)

Finding dSYMs while archiving project

  • Archive the project.
  • dSYMs are placed inside of an .xcarchive of your project.
  • Open Xcode -> Window -> Organizer
  • Click on archive and select Show in Finder alt text
  • Click on Show Package Contents alt text
  • Search for dSYMs directory alt text
  • Zip all the dSYM files and upload to Backtrace services (see: Symbolification)

Github

link
Stars: 0
Help us keep the lights on

Dependencies

Used By

Total: 0

Releases

1.5.0 - May 6, 2019

Adding tvOS support includes:

  • Adding new target and shared scheme for tvOS
  • Updating README.md and .travis.yaml config file
  • Adding crashing action to the demo app
  • Adding shared scheme for tvOS example application
  • Updating default logging level
  • Updating Backtrace.podspec

Note: This version requires at least Backtrace-PLCrashReporter version 1.5.0

1.4.1 - Apr 2, 2019

  • Add comments in public definitions
  • Add table of contents to README.md
  • Rename userAttributes to attributes
  • Update example projects

1.4.0 - Mar 26, 2019

File attachments

  • Add file attachments support
  • Send attachments using multipart
  • Store attachment paths in CoreData
  • Add file reading option .mappedIfSafe

Default attribubutes

  • Add default attributes for network and Bluetooth status
  • Expose attachment path in public API
  • Add default attributes for:
    • guid - unique user identifier
    • error.message
    • hostaname
    • lang.name
    • lang.version
    • NFC
    • location

Handling all exceptions on macOS

  • Handle crashes on macOS by BacktraceCrashExceptionApplication

Documentation

  • Update documentation
  • Update README.md
  • Update BacktraceClientConfiguration

Tests

  • Add mocks for URLSession
  • Add mocks for HTTP responses
  • Improve code coverage

Checking the debugger attachment

  • Run CrashReporter only when the debugger is detached
  • Add reporting policy
  • Check if the debugger is attached

1.3.0 - Mar 5, 2019

  • Add support for default attributes
  • Add support for user-defined attributes
  • Handle saving all kind of attributes on crash-time
  • Simplified library API
  • Add more customization for BacktraceClient implementation