Skip to content

Commit

Permalink
Add file attachment support
Browse files Browse the repository at this point in the history
* Add default attributes for network and Bluetooth status
* Add attachment paths
* Expose attachment path in public API
* Send attachments using multipart
* Store attachment paths in CoreData
* Add file reading option .mappedIfSafe
* Handle crashes on macOS by BacktraceCrashExceptionApplication
* Update documentation
* Add mocks for URLSession
* Add mocks for HTTP responses
* Improve code coverage
* Run CrashReporter only when the debugger is detached
* Add reporting policy
* Check if the debugger is attached
* Update BacktraceClientConfiguration
* Add additional attributes for NFC and location
* Update README.md
* Add default attributes for: 
- `guid` - unique user identifier
- `error.message` 
- `hostaname`
- `lang.name`
- `lang.version`
- NFC
- location
  • Loading branch information
krml19 authored Mar 26, 2019
1 parent b731eae commit 2f449f9
Show file tree
Hide file tree
Showing 62 changed files with 1,988 additions and 486 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ opt_in_rules: # some rules are only opt-in
# swiftlint rules
included: # paths to include during linting. `--path` is ignored if present.
- Sources
- Tests
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
Expand Down
11 changes: 11 additions & 0 deletions Backtrace-macOS/BacktraceCrashExceptionApplication.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Cocoa

/// `NSApplication` subclass to catch additional exceptions on macOS
@objc public class BacktraceCrashExceptionApplication: NSApplication {

/// Catch all exceptions and send them to `Backtrace`
public override func reportException(_ exception: NSException) {
super.reportException(exception)
BacktraceClient.shared?.send(exception: exception, attachmentPaths: [], completion: {_ in })
}
}
6 changes: 3 additions & 3 deletions Backtrace.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Pod::Spec.new do |s|

s.name = "Backtrace"
s.version = "1.3.0"
s.version = "1.4.0"
s.summary = "Backtrace's integration with iOS and macOS"
s.description = "Backtrace's integration with iOS and macOS for handling crashes"
s.homepage = "https://backtrace.io/"
Expand All @@ -20,8 +20,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "10.0"
s.osx.deployment_target = "10.10"

s.ios.source_files = ["Sources/**/*.{swift}", "Backtrace-iOS/**/*.h*"]
s.osx.source_files = ["Sources/**/*.{swift}", "Backtrace-macOS/**/*.h*"]
s.ios.source_files = ["Sources/**/*.{swift}", "Backtrace-iOS/**/*.{h*,swift}"]
s.osx.source_files = ["Sources/**/*.{swift}", "Backtrace-macOS/**/*.{h*,swift}"]

s.ios.public_header_files = ["Backtrace-iOS/**/*.h*"]
s.osx.public_header_files = ["Backtrace-macOS/**/*.h*"]
Expand Down
224 changes: 183 additions & 41 deletions Backtrace.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Backtrace.xcodeproj/xcshareddata/xcschemes/Backtrace-iOS.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,18 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2C2FA4F21BBD26300934744"
BuildableName = "Backtrace.framework"
BlueprintName = "Backtrace-iOS"
ReferencedContainer = "container:Backtrace.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
Expand Down
25 changes: 20 additions & 5 deletions Example-iOS-ObjC/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
token: @"token"];
BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration alloc] initWithCredentials: credentials
dbSettings: [BacktraceDatabaseSettings new]
reportsPerMin: 3];
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: TRUE];
BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil];
BacktraceClient.shared.delegate = self;

Expand All @@ -22,7 +32,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
NSArray *array = @[];
NSObject *object = array[1]; // will throw exception
} @catch (NSException *exception) {
[[BacktraceClient shared] sendWithException: exception completion:^(BacktraceResult * _Nonnull result) {
NSArray *paths = @[[[NSBundle mainBundle] pathForResource: @"test" ofType: @"txt"]];
[[BacktraceClient shared] sendWithAttachmentPaths: paths completion: ^(BacktraceResult * _Nonnull result) {
NSLog(@"%@", result);
}];
} @finally {
Expand All @@ -31,7 +42,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

//sending NSError
NSError *error = [NSError errorWithDomain: @"backtrace.domain" code: 100 userInfo: @{}];
[[BacktraceClient shared] sendWithCompletion:^(BacktraceResult * _Nonnull result) {
NSArray *paths = @[[[NSBundle mainBundle] pathForResource: @"test" ofType: @"txt"]];
[[BacktraceClient shared] sendWithAttachmentPaths: paths completion: ^(BacktraceResult * _Nonnull result) {
NSLog(@"%@", result);
}];

Expand All @@ -40,6 +52,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

#pragma mark - BacktraceClientDelegate
- (BacktraceReport *)willSend:(BacktraceReport *)report {
NSMutableDictionary *dict = [report.attributes mutableCopy];
[dict setObject: @"just before send" forKey: @"added"];
report.attributes = dict;
return report;
}

Expand Down
3 changes: 2 additions & 1 deletion Example-iOS-ObjC/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ - (void)viewDidLoad {

}
- (IBAction) liveReportAction: (id) sender {
[[BacktraceClient shared] sendWithCompletion:^(BacktraceResult * _Nonnull result) {
NSArray *paths = @[@"/home/test.txt"];
[[BacktraceClient shared] sendWithAttachmentPaths:paths completion:^(BacktraceResult * _Nonnull result) {
NSLog(@"%@", result.message);
}];
}
Expand Down
3 changes: 3 additions & 0 deletions Example-iOS-ObjC/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test from iOS simulator
test Example-iOS-ObjC
backtrace sample text file
18 changes: 15 additions & 3 deletions Example-iOS/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://backtrace.io")!,
token: "token")
let configuration = BacktraceClientConfiguration(credentials: backtraceCredentials)
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,
allowsAttachingDebugger: true)

BacktraceClient.shared = try? BacktraceClient(configuration: configuration)
BacktraceClient.shared = try? BacktraceClient(configuration: backtraceConfiguration)
BacktraceClient.shared?.delegate = self
BacktraceClient.shared?.userAttributes = ["foo": "bar", "testing": true]

do {
try throwingFunc()
} catch {
BacktraceClient.shared?.send { (result) in
let filePath = Bundle.main.path(forResource: "test", ofType: "txt")!
BacktraceClient.shared?.send(attachmentPaths: [filePath]) { (result) in
print(result)
}
}
Expand All @@ -38,6 +49,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

extension AppDelegate: BacktraceClientDelegate {
func willSend(_ report: BacktraceReport) -> (BacktraceReport) {
report.attributes["added"] = "just before send"
return report
}

Expand Down
11 changes: 9 additions & 2 deletions Example-iOS/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ class ViewController: UIViewController {
}

@IBAction func liveReportAction(_ sender: Any) {
BacktraceClient.shared?.send { (result) in
// Sned autogenerated report
// BacktraceClient.shared?.send(attachmentPaths: [], completion: { (result) in
// print(result)
// })

// Send NSException
let exception = NSException(name: NSExceptionName.characterConversionException, reason: "cusotm reason", userInfo: ["testUserInfo": "tests"])
BacktraceClient.shared?.send(exception: exception, attachmentPaths: [], completion: { (result: BacktraceResult) in
print(result)
}
})
}

@IBAction func crashAppAction(_ sender: Any) {
Expand Down
3 changes: 3 additions & 0 deletions Example-iOS/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test from iOS simulator
test Example-iOS
backtrace sample text file
48 changes: 42 additions & 6 deletions Example-macOS-ObjC/AppDelegate.m
Original file line number Diff line number Diff line change
@@ -1,38 +1,74 @@
#import "AppDelegate.h"
@import Backtrace;

@interface AppDelegate ()
@interface AppDelegate () <BacktraceClientDelegate>

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
token: @"token"];
BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration alloc] initWithCredentials: credentials
dbSettings: [BacktraceDatabaseSettings new]
reportsPerMin: 3];
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: TRUE];
BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil];
[BacktraceClient.shared setUserAttributes: @{@"foo": @"bar"}];
BacktraceClient.shared.delegate = self;

@try {
NSArray *array = @[];
NSObject *object = array[1]; //will throw exception
} @catch (NSException *exception) {
[[BacktraceClient shared] sendWithCompletion:^(BacktraceResult * _Nonnull result) {
NSArray *paths = @[[[NSBundle mainBundle] pathForResource: @"test" ofType: @"txt"]];
[[BacktraceClient shared] sendWithAttachmentPaths: paths completion: ^(BacktraceResult * _Nonnull result) {
NSLog(@"%@", result);
}];
} @finally {

}

}


- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}

#pragma mark - BacktraceClientDelegate
- (BacktraceReport *)willSend:(BacktraceReport *)report {
NSMutableDictionary *dict = [report.attributes mutableCopy];
[dict setObject: @"just before send" forKey: @"added"];
report.attributes = dict;
return report;
}

- (void)serverDidFail:(NSError *)error {

}

- (void)serverDidResponse:(BacktraceResult *)result {

}

- (NSURLRequest *)willSendRequest:(NSURLRequest *)request {
return request;
}

- (void)didReachLimit:(BacktraceResult *)result {

}

@end
4 changes: 2 additions & 2 deletions Example-macOS-ObjC/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSPrincipalClass</key>
<string>Backtrace.BacktraceCrashExceptionApplication</string>
</dict>
</plist>
3 changes: 3 additions & 0 deletions Example-macOS-ObjC/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test from macOS
test Example-macOS-ObjC
backtrace sample text file
Loading

0 comments on commit 2f449f9

Please sign in to comment.