Skip to content

Commit

Permalink
Merge pull request #291 from bugsnag/next
Browse files Browse the repository at this point in the history
Next release: v5.16.0
  • Loading branch information
fractalwrench authored Jul 2, 2018
2 parents 39d258b + 2316564 commit b5f5ae9
Show file tree
Hide file tree
Showing 29 changed files with 624 additions and 80 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
language: objective-c
cache: bundler
cache:
- bundler
- cocoapods
rvm: 2.3.7
matrix:
include:
Expand Down
4 changes: 2 additions & 2 deletions Bugsnag.podspec.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Bugsnag",
"version": "5.15.6",
"version": "5.16.0",
"summary": "Cocoa notifier for SDK for bugsnag.com",
"homepage": "https://bugsnag.com",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
},
"source": {
"git": "https://github.com/bugsnag/bugsnag-cocoa.git",
"tag": "v5.15.6"
"tag": "v5.16.0"
},
"frameworks": ["Foundation", "SystemConfiguration"],
"libraries": [
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
Changelog
=========

## 5.16.0 (02 Jul 2018)

This release alters the behaviour of the notifier to track sessions automatically.
A session will be automatically captured on each app launch and sent to [https://sessions.bugsnag.com](https://sessions.bugsnag.com).

If you use Bugsnag On-Premise, it is now also recommended that you set your notify and session endpoints via `config.setEndpoints(notify:sessions:)`. The previous properties used to configure this, `config.notifyURL` and `config.sessionURL`, are now `readonly` and therefore no longer assignable.

* Enable automatic session tracking by default [#286](https://github.com/bugsnag/bugsnag-cocoa/pull/286)

### Bug Fixes

* Handle potential nil content value in RegisterErrorData class [#289](https://github.com/bugsnag/bugsnag-cocoa/pull/289)

## 5.15.6 (30 May 2018)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion Source/BugsnagApiClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ - (void)sendData:(id)data
NSError *error = nil;
NSData *jsonData =
[NSJSONSerialization dataWithJSONObject:payload
options:NSJSONWritingPrettyPrinted
options:0
error:&error];

if (jsonData == nil) {
Expand Down
47 changes: 38 additions & 9 deletions Source/BugsnagConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@
typedef void (^BugsnagNotifyBlock)(BugsnagCrashReport *_Nonnull report);

/**
* A handler for modifying data before sending it to Bugsnag
* A handler for modifying data before sending it to Bugsnag.
*
* beforeSendBlocks will be invoked on a dedicated
* background queue, which will be different from the queue where the block was originally added.
*
* @param rawEventData The raw event data written at crash time. This
* includes data added in onCrashHandler.
Expand Down Expand Up @@ -70,10 +73,6 @@ typedef NSDictionary *_Nullable (^BugsnagBeforeNotifyHook)(
* The API key of a Bugsnag project
*/
@property(readwrite, retain, nullable) NSString *apiKey;
/**
* The URL used to notify Bugsnag
*/
@property(readwrite, retain, nullable) NSURL *notifyURL;
/**
* The release stage of the application, such as production, development, beta
* et cetera
Expand Down Expand Up @@ -139,15 +138,45 @@ BugsnagBreadcrumbs *breadcrumbs;
@property BOOL autoNotify;

/**
* Determines whether app sessions should be tracked automatically. By default this value is false.
* Determines whether app sessions should be tracked automatically. By default this value is true.
*/
@property BOOL shouldAutoCaptureSessions;

/**
* Set the endpoint to which tracked sessions reports are sent. This defaults to https://sessions.bugsnag.com,
* but should be overridden if you are using Bugsnag On-premise, to point to your own Bugsnag endpoint.
* Retrieves the endpoint used to notify Bugsnag of errors
*
* NOTE: If you want to set this value, you should do so via setEndpointsForNotify:sessions: instead.
*
* @see setEndpointsForNotify:sessions:
*/
@property(readonly, retain, nullable) NSURL *notifyURL;

/**
* Retrieves the endpoint used to send tracked sessions to Bugsnag
*
* NOTE: If you want to set this value, you should do so via setEndpointsForNotify:sessions: instead.
*
* @see setEndpointsForNotify:sessions:
*/
@property(readwrite, retain, nullable) NSURL *sessionURL;
@property(readonly, retain, nullable) NSURL *sessionURL;

/**
* Set the endpoints to send data to. By default we'll send error reports to
* https://notify.bugsnag.com, and sessions to https://sessions.bugsnag.com, but you can
* override this if you are using Bugsnag Enterprise to point to your own Bugsnag endpoint.
*
* Please note that it is recommended that you set both endpoints. If the notify endpoint is
* missing, an assertion will be thrown. If the session endpoint is missing, a warning will be
* logged and sessions will not be sent automatically.
*
* @param notify the notify endpoint
* @param sessions the sessions endpoint
*
* @throws an assertion if the notify endpoint is not a valid URL
*/

- (void)setEndpointsForNotify:(NSString *_Nonnull)notify
sessions:(NSString *_Nonnull)sessions NS_SWIFT_NAME(setEndpoints(notify:sessions:));

/**
* Set user metadata
Expand Down
22 changes: 20 additions & 2 deletions Source/BugsnagConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ - (id)init {
_notifyReleaseStages = nil;
_breadcrumbs = [BugsnagBreadcrumbs new];
_automaticallyCollectBreadcrumbs = YES;
_shouldAutoCaptureSessions = YES;

if ([NSURLSession class]) {
_session = [NSURLSession
sessionWithConfiguration:[NSURLSessionConfiguration
Expand All @@ -87,7 +89,7 @@ - (BOOL)shouldSendReports {
- (void)setUser:(NSString *)userId
withName:(NSString *)userName
andEmail:(NSString *)userEmail {

self.currentUser = [[BugsnagUser alloc] initWithUserId:userId name:userName emailAddress:userEmail];

[self.metaData addAttribute:BSGKeyId withValue:userId toTabWithName:BSGKeyUser];
Expand Down Expand Up @@ -225,7 +227,7 @@ - (BOOL)shouldAutoCaptureSessions {
- (void)setShouldAutoCaptureSessions:(BOOL)shouldAutoCaptureSessions {
@synchronized (self) {
_shouldAutoCaptureSessions = shouldAutoCaptureSessions;

if (shouldAutoCaptureSessions) { // track any existing sessions
BugsnagSessionTracker *sessionTracker = [Bugsnag notifier].sessionTracker;
[sessionTracker onAutoCaptureEnabled];
Expand All @@ -249,6 +251,22 @@ - (NSDictionary *)sessionApiHeaders {
};
}

- (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_Nonnull)sessions {
_notifyURL = [NSURL URLWithString:notify];
_sessionURL = [NSURL URLWithString:sessions];

NSAssert([self isValidUrl:_notifyURL], @"Invalid URL supplied for notify endpoint");

if (![self isValidUrl:_sessionURL]) {
_sessionURL = nil;
}
}

- (BOOL)isValidUrl:(NSURL *)url {
return url != nil && url.scheme != nil && url.host != nil;
}


- (BOOL)hasValidApiKey {
return [_apiKey length] > 0;
}
Expand Down
9 changes: 8 additions & 1 deletion Source/BugsnagCrashReport.m
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,16 @@ + (instancetype)errorDataFromThreads:(NSArray *)threads {
}
NSString *contentValue = data[@"value"];

#pragma clang diagnostic push
#pragma ide diagnostic ignored "OCDFAInspection"
if (contentValue == nil || ![contentValue isKindOfClass:[NSString class]]) {
continue;
}
#pragma clang diagnostic pop

if ([self isReservedWord:contentValue]) {
reservedWord = contentValue;
} else if (!([[contentValue componentsSeparatedByString:@"/"] count] > 2)) {
} else if ([[contentValue componentsSeparatedByString:@"/"] count] <= 2) {
// must be a string that isn't a reserved word and isn't a filepath
[interestingValues addObject:contentValue];
}
Expand Down
8 changes: 3 additions & 5 deletions Source/BugsnagNotifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#import <AppKit/AppKit.h>
#endif

NSString *const NOTIFIER_VERSION = @"5.15.6";
NSString *const NOTIFIER_VERSION = @"5.16.0";
NSString *const NOTIFIER_URL = @"https://github.com/bugsnag/bugsnag-cocoa";
NSString *const BSTabCrash = @"crash";
NSString *const BSAttributeDepth = @"depth";
Expand Down Expand Up @@ -216,9 +216,6 @@ - (id)initWithConfiguration:(BugsnagConfiguration *)initConfiguration {
hasRecordedSessions = true;
}];


[self.sessionTracker startNewSession:[NSDate date] withUser:nil autoCaptured:YES];

[self metaDataChanged:self.configuration.metaData];
[self metaDataChanged:self.configuration.config];
[self metaDataChanged:self.state];
Expand Down Expand Up @@ -356,9 +353,10 @@ - (void)start {
object:nil];
#endif

_started = YES;

// notification not received in time on initial startup, so trigger manually
[self willEnterForeground:self];
_started = YES;
}

- (void)watchLifecycleEvents:(NSNotificationCenter *)center {
Expand Down
64 changes: 38 additions & 26 deletions Source/BugsnagSessionTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "BSG_KSLogger.h"
#import "BugsnagSessionTrackingPayload.h"
#import "BugsnagSessionTrackingApiClient.h"
#import "BugsnagLogger.h"

@interface BugsnagSessionTracker ()
@property BugsnagConfiguration *config;
Expand Down Expand Up @@ -43,6 +44,10 @@ - (instancetype)initWithConfig:(BugsnagConfiguration *)config
- (void)startNewSession:(NSDate *)date
withUser:(BugsnagUser *)user
autoCaptured:(BOOL)autoCaptured {
if (self.config.sessionURL == nil) {
bsg_log_err(@"The session tracking endpoint has not been set. Session tracking is disabled");
return;
}

_currentSession = [[BugsnagSession alloc] initWithId:[[NSUUID UUID] UUIDString]
startDate:date
Expand All @@ -58,7 +63,7 @@ - (void)startNewSession:(NSDate *)date
- (void)trackSession {
[self.sessionStore write:self.currentSession];
self.trackedFirstSession = YES;

if (self.callback) {
self.callback(self.currentSession);
}
Expand Down Expand Up @@ -87,34 +92,41 @@ - (void)incrementHandledError {
}

- (void)send {
@synchronized (self.sessionStore) {
NSMutableArray *sessions = [NSMutableArray new];
NSArray *fileIds = [self.sessionStore fileIds];
NSArray *fileIds = [self.sessionStore fileIds];

for (NSDictionary *dict in [self.sessionStore allFiles]) {
[sessions addObject:[[BugsnagSession alloc] initWithDictionary:dict]];
}
BugsnagSessionTrackingPayload *payload = [[BugsnagSessionTrackingPayload alloc] initWithSessions:sessions];

if (payload.sessions.count > 0) {
[self.apiClient sendData:payload
withPayload:[payload toJson]
toURL:self.config.sessionURL
headers:self.config.sessionApiHeaders
onCompletion:^(id data, BOOL success, NSError *error) {

if (success && error == nil) {
NSLog(@"Sent sessions to Bugsnag");

for (NSString *fileId in fileIds) {
[self.sessionStore deleteFileWithId:fileId];
}
} else {
NSLog(@"Failed to send sessions to Bugsnag: %@", error);
if (fileIds.count <= 0) {
return;
}

dispatch_semaphore_t requestSemaphore = dispatch_semaphore_create(0);
NSMutableArray *sessions = [NSMutableArray new];

for (NSDictionary *dict in [self.sessionStore allFiles]) {
[sessions addObject:[[BugsnagSession alloc] initWithDictionary:dict]];
}
BugsnagSessionTrackingPayload *payload = [[BugsnagSessionTrackingPayload alloc] initWithSessions:sessions];

if (payload.sessions.count > 0) {
[self.apiClient sendData:payload
withPayload:[payload toJson]
toURL:self.config.sessionURL
headers:self.config.sessionApiHeaders
onCompletion:^(id data, BOOL success, NSError *error) {
if (success && error == nil) {
NSLog(@"Sent sessions to Bugsnag");

for (NSString *fileId in fileIds) {
[self.sessionStore deleteFileWithId:fileId];
}
}];
}
} else {
NSLog(@"Failed to send sessions to Bugsnag: %@", error);
}
dispatch_semaphore_signal(requestSemaphore);
}];
} else {
dispatch_semaphore_signal(requestSemaphore);
}
dispatch_semaphore_wait(requestSemaphore, DISPATCH_TIME_FOREVER);
}

@end
6 changes: 3 additions & 3 deletions Source/BugsnagUser.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ @implementation BugsnagUser
- (instancetype)initWithDictionary:(NSDictionary *)dict {
if (self = [super init]) {
_userId = dict[@"id"];
_emailAddress = dict[@"emailAddress"];
_emailAddress = dict[@"email"];
_name = dict[@"name"];
}
return self;
Expand All @@ -34,12 +34,12 @@ + (instancetype)userWithUserId:(NSString *)userId name:(NSString *)name emailAdd
return [[self alloc] initWithUserId:userId name:name emailAddress:emailAddress];
}


- (NSDictionary *)toJson {
NSMutableDictionary *dict = [NSMutableDictionary new];
BSGDictInsertIfNotNil(dict, self.userId, @"id");
BSGDictInsertIfNotNil(dict, self.emailAddress, @"emailAddress");
BSGDictInsertIfNotNil(dict, self.emailAddress, @"email");
BSGDictInsertIfNotNil(dict, self.name, @"name");
return [NSDictionary dictionaryWithDictionary:dict];
}

@end
Loading

0 comments on commit b5f5ae9

Please sign in to comment.