diff --git a/Classes/BITCrashManager.h b/Classes/BITCrashManager.h index 98679c598d..c411639bbe 100644 --- a/Classes/BITCrashManager.h +++ b/Classes/BITCrashManager.h @@ -30,11 +30,14 @@ #import +// hockey crash manager status +typedef enum { + BITCrashManagerStatusDisabled = 0, + BITCrashManagerStatusAlwaysAsk = 1, + BITCrashManagerStatusAutoSend = 2 +} BITCrashManagerStatus; +static NSString *kBITCrashManagerStatus = @"BITCrashManagerStatus"; -typedef enum BITCrashAlertType { - BITCrashAlertTypeSend = 0, - BITCrashAlertTypeFeedback = 1, -} BITCrashAlertType; typedef enum BITCrashStatus { BITCrashStatusQueued = -80, @@ -95,7 +98,6 @@ typedef enum BITCrashStatus { NSFileManager *_fileManager; BOOL _crashIdenticalCurrentVersion; - BOOL _crashReportDisabled; NSMutableArray *_crashFiles; @@ -124,20 +126,32 @@ typedef enum BITCrashStatus { /// @name Configuration ///----------------------------------------------------------------------------- -/** - Flag that determines if crashes should be send without user interaction +/** Set the default status of the Crash Manager - If enabled, new crashes will not cause an alert to show up asking the user - if he or she agrees on sending the crash report to the server. + Defines if the crash reporting feature should be disabled, ask the user before + sending each crash report or send crash reportings automatically without + asking.. This must be assigned one of the following: - By default a crash report is anonymous, unless you are adding personal information - using the `userName`, `userEmail` or `[BITCrashManagerDelegate applicationLogForCrashManager:]` - options. For privacy reasons you should give the user an option not to send - the reports. + - `BITCrashManagerStatusDisabled`: Crash reporting is disabled + - `BITCrashManagerStatusAlwaysAsk`: User is asked each time before sending + - `BITCrashManagerStatusAutoSend`: Each crash report is send automatically - *Default*: _NO_ + The default value is `BITCrashManagerStatusAlwaysAsk`. You can allow the user + to switch from `BITCrashManagerStatusAlwaysAsk` to + `BITCrashManagerStatusAutoSend` by setting `showAlwaysButton` + to _YES_. + + The current value is always stored in User Defaults with the key + "BITCrashManagerStatus". + + If you intend to implement a user setting to let them enable or disable + crash reporting, this delegate should be used to return that value. You also + have to make sure the new value is stored in the UserDefaults with the key + "BITCrashManagerStatus". + + @see showAlwaysButton */ -@property (nonatomic, assign, getter=isAutoSubmitCrashReport) BOOL autoSubmitCrashReport; +@property (nonatomic, assign) BITCrashManagerStatus crashManagerStatus; /** @@ -150,12 +164,11 @@ typedef enum BITCrashStatus { alert will be presented. @warning This will cause the dialog not to show the alert description text landscape mode! - @see autoSubmitCrashReport + @see crashManagerStatus */ @property (nonatomic, assign, getter=isShowingAlwaysButton) BOOL showAlwaysButton; -// if YES, the user will be presented with a status of the crash, if known -// if NO, the user will not see any feedback information (default) + /** Flag that determines if the user should get feedback about the crash diff --git a/Classes/BITCrashManager.m b/Classes/BITCrashManager.m index 672e05218e..b22f9188cd 100644 --- a/Classes/BITCrashManager.m +++ b/Classes/BITCrashManager.m @@ -55,6 +55,12 @@ #define kBITCrashUserEmail @"HockeySDKCrashUserEmail" +typedef enum BITCrashAlertType { + BITCrashAlertTypeSend = 0, + BITCrashAlertTypeFeedback = 1, +} BITCrashAlertType; + + @interface BITCrashManager () @property (nonatomic, retain) NSFileManager *fileManager; @@ -64,9 +70,9 @@ @implementation BITCrashManager @synthesize delegate = _delegate; +@synthesize crashManagerStatus = _crashManagerStatus; @synthesize showAlwaysButton = _showAlwaysButton; @synthesize feedbackActivated = _feedbackActivated; -@synthesize autoSubmitCrashReport = _autoSubmitCrashReport; @synthesize didCrashInLastSession = _didCrashInLastSession; @synthesize timeintervalCrashInLastSessionOccured = _timeintervalCrashInLastSessionOccured; @@ -82,7 +88,6 @@ _delegate = nil; _feedbackActivated = NO; _showAlwaysButton = NO; - _autoSubmitCrashReport = NO; _serverResult = BITCrashStatusUnknown; _crashIdenticalCurrentVersion = YES; @@ -101,12 +106,16 @@ _analyzerStarted = 0; } - _crashReportDisabled = NO; - if (self.delegate != nil && [self.delegate respondsToSelector:@selector(shouldDisableCrashManager:)]) { - _crashReportDisabled = [self.delegate shouldDisableCrashManager:self]; + _crashManagerStatus = BITCrashManagerStatusAlwaysAsk; + + testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kBITCrashManagerStatus]; + if (testValue) { + _crashManagerStatus = [[NSUserDefaults standardUserDefaults] integerForKey:kBITCrashManagerStatus]; + } else { + [[NSUserDefaults standardUserDefaults] setInteger:_crashManagerStatus forKey:kBITCrashManagerStatus]; } - if (!_crashReportDisabled) { + if (_crashManagerStatus != BITCrashManagerStatusDisabled) { _crashFiles = [[NSMutableArray alloc] init]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); _crashesDir = [[NSString stringWithFormat:@"%@", [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/crashes/"]] retain]; @@ -165,22 +174,15 @@ } -#pragma mark - private methods - -- (BOOL)autoSendCrashReports { - BOOL result = NO; +- (void)setCrashManagerStatus:(BITCrashManagerStatus)crashManagerStatus { + _crashManagerStatus = crashManagerStatus; - if (!self.autoSubmitCrashReport) { - if (self.isShowingAlwaysButton && [[NSUserDefaults standardUserDefaults] boolForKey: kBITCrashAutomaticallySendReports]) { - result = YES; - } - } else { - result = YES; - } - - return result; + [[NSUserDefaults standardUserDefaults] setInteger:crashManagerStatus forKey:kBITCrashManagerStatus]; } + +#pragma mark - private methods + // begin the startup process - (void)startManager { if (!_sendingInProgress && [self hasPendingCrashReport]) { @@ -188,7 +190,7 @@ if (!BITHockeyBundle()) { NSLog(@"WARNING: HockeySDKResource.bundle is missing, sending reports automatically!"); [self sendCrashReports]; - } else if (![self autoSendCrashReports] && [self hasNonApprovedCrashReports]) { + } else if (_crashManagerStatus != BITCrashManagerStatusAutoSend && [self hasNonApprovedCrashReports]) { if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashManagerWillShowSubmitCrashReportAlert:)]) { [self.delegate crashManagerWillShowSubmitCrashReportAlert:self]; @@ -293,7 +295,7 @@ } - (BOOL)hasPendingCrashReport { - if (!_crashReportDisabled) { + if (_crashManagerStatus != BITCrashManagerStatusDisabled) { if ([_crashFiles count] == 0 && [self.fileManager fileExistsAtPath:_crashesDir]) { NSString *file = nil; NSError *error = NULL; diff --git a/Classes/BITCrashManagerDelegate.h b/Classes/BITCrashManagerDelegate.h index 045550bdc1..f4d8dc5302 100644 --- a/Classes/BITCrashManagerDelegate.h +++ b/Classes/BITCrashManagerDelegate.h @@ -38,23 +38,6 @@ @optional -///----------------------------------------------------------------------------- -/// @name Privacy -///----------------------------------------------------------------------------- - -/** Return YES if the crash reporting module should be disabled - - The crash reporting module is enabled by default. Implement this delegate and - return YES if you want to disable it. - - If you intend to implement a user setting to let them enable or disable - crash reporting, this delegate should be used to return that value. - - @param crashManager The `BITCrashManager` instance invoking this delegate - */ -- (BOOL)shouldDisableCrashManager:(BITCrashManager *)crashManager; - - ///----------------------------------------------------------------------------- /// @name Additional meta data ///----------------------------------------------------------------------------- @@ -62,6 +45,8 @@ /** Return any log string based data the crash report being processed should contain @param crashManager The `BITCrashManager` instance invoking this delegate + @see userNameForCrashManager: + @see userEmailForCrashManager: */ -(NSString *)applicationLogForCrashManager:(BITCrashManager *)crashManager; @@ -70,6 +55,8 @@ /** Return the user name or userid that should be send along each crash report @param crashManager The `BITCrashManager` instance invoking this delegate + @see applicationLogForCrashManager: + @see userEmailForCrashManager: @warning When returning a non nil value, crash reports are not anonymous any more and the alerts will not show the "anonymous" word! */ @@ -80,6 +67,8 @@ /** Return the users email address that should be send along each crash report @param crashManager The `BITCrashManager` instance invoking this delegate + @see applicationLogForCrashManager: + @see userNameForCrashManager: @warning When returning a non nil value, crash reports are not anonymous any more and the alerts will not show the "anonymous" word! */ diff --git a/README.md b/README.md index 1d970bc048..9943fb692e 100644 --- a/README.md +++ b/README.md @@ -103,5 +103,5 @@ As an alternative for step 5 and 6, you can use our [HockeyMac](https://github.c 1. Check if the `BETA_IDENTIFIER` or `LIVE_IDENTIFIER` matches the App ID in HockeyApp. 2. Check if CFBundleIdentifier in your Info.plist matches the Bundle Identifier of the app in HockeyApp. HockeyApp accepts crashes only if both the App ID and the Bundle Identifier equal their corresponding values in your plist and source code. -3. Unless you have set `[BITCrashManager setAutoSubmitCrashReport:]` to `YES`: If your app crashes and you start it again, is the alert shown which asks the user to send the crash report? If not, please crash your app again, then connect the debugger and set a break point in `BITCrashManager.m`, method `startManager` to see why the alert is not shown. +3. Unless you have set `[BITCrashManager setCrashManagerStatus:]` to `BITCrashManagerStatusAutoSubmit`: If your app crashes and you start it again, is the alert shown which asks the user to send the crash report? If not, please crash your app again, then connect the debugger and set a break point in `BITCrashManager.m`, method `startManager` to see why the alert is not shown. 4. If it still does not work, please [contact us](http://support.hockeyapp.net/discussion/new).