Skip to content

Add a mechanism to specify dynamic key-value pairs in the prefill email body of a bug report #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Aardvark.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Aardvark'
s.version = '1.1.3'
s.version = '1.2.0'
s.license = 'Apache License, Version 2.0'
s.summary = 'Aardvark is a library that makes it dead simple to create actionable bug reports.'
s.homepage = 'https://github.com/square/Aardvark'
Expand Down
14 changes: 14 additions & 0 deletions Bug Reporting/ARKEmailBugReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,24 @@
#import <MessageUI/MessageUI.h>


@class ARKEmailBugReporter;
@class ARKLogStore;
@protocol ARKLogFormatter;


NS_ASSUME_NONNULL_BEGIN


@protocol ARKEmailBugReporterEmailBodyAdditionsDelegate <NSObject>

@required

/// Called on the main thread when a bug is filed. The key/value pairs in the returned dictionary will be appended to the bug report below the prefilledEmailBody.
- (nullable NSDictionary *)emailBodyAdditionsForEmailBugReporter:(ARKEmailBugReporter *)emailBugReporter;

@end


/// Composes a bug report that is sent via email.
@interface ARKEmailBugReporter : NSObject <ARKBugReporter>

Expand All @@ -40,6 +51,9 @@ NS_ASSUME_NONNULL_BEGIN
/// The email body that will be presented to the user when they compose a report.
@property (nonatomic, copy) NSString *prefilledEmailBody;

/// The email body delegate, responsible for providing key/value pairs to include in the bug report at the time the bug is filed.
@property (nullable, nonatomic, weak) id <ARKEmailBugReporterEmailBodyAdditionsDelegate> emailBodyAdditionsDelegate;

/// The formatter used to prepare the log for entry into an email. Defaults to a vanilla instance of ARKDefaultLogFormatter.
@property (nonatomic) id <ARKLogFormatter> logFormatter;

Expand Down
28 changes: 23 additions & 5 deletions Bug Reporting/ARKEmailBugReporter.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ - (instancetype)init;
@"2. \n"
@"3. \n"
@"\n"
@"System version: %@\n", [[UIDevice currentDevice] systemVersion]];
@"System version: %@", [[UIDevice currentDevice] systemVersion]];

_logFormatter = [ARKDefaultLogFormatter new];
_numberOfRecentErrorLogsToIncludeInEmailBodyWhenAttachmentsAreAvailable = 3;
Expand Down Expand Up @@ -182,6 +182,7 @@ - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)
NSString *bugTitle = [alertView textFieldAtIndex:0].text;
NSArray *logStores = [self.logStores copy];
NSMapTable *logStoresToLogMessagesMap = [NSMapTable new];
NSDictionary *emailBodyAdditions = [self.emailBodyAdditionsDelegate emailBodyAdditionsForEmailBugReporter:self];

if ([MFMailComposeViewController canSendMail]) {
self.mailComposeViewController = [MFMailComposeViewController new];
Expand All @@ -195,7 +196,8 @@ - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)

// Only attach data once all log messages have been retrieved.
if (logStoresToLogMessagesMap.count == logStores.count) {
NSMutableString *emailBody = [NSMutableString stringWithFormat:@"%@\n", self.prefilledEmailBody];
NSMutableString *emailBody = [self _prefilledEmailBodyWithEmailBodyAdditions:emailBodyAdditions];

for (ARKLogStore *logStore in logStores) {
NSArray *logMessages = [logStoresToLogMessagesMap objectForKey:logStore];

Expand Down Expand Up @@ -245,11 +247,11 @@ - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)

// Only append logs once all log messages have been retrieved.
if (logStoresToLogMessagesMap.count == logStores.count) {
NSMutableString *emailBody = [NSMutableString new];
NSMutableString *emailBody = [self _prefilledEmailBodyWithEmailBodyAdditions:emailBodyAdditions];

for (ARKLogStore *logStore in logStores) {
NSArray *logMessages = [logStoresToLogMessagesMap objectForKey:logStore];

[emailBody appendFormat:@"%@\n%@\n", self.prefilledEmailBody, [self _recentErrorLogMessagesAsPlainText:logMessages count:self.numberOfRecentErrorLogsToIncludeInEmailBodyWhenAttachmentsAreUnavailable]];
[emailBody appendFormat:@"%@\n", [self _recentErrorLogMessagesAsPlainText:logMessages count:self.numberOfRecentErrorLogsToIncludeInEmailBodyWhenAttachmentsAreUnavailable]];
}

NSURL *composeEmailURL = [self _emailURLWithRecipients:@[self.bugReportRecipientEmailAddress] CC:@"" subject:bugTitle body:emailBody];
Expand Down Expand Up @@ -368,6 +370,22 @@ - (void)_dismissEmailComposeWindow;
}
}

- (NSMutableString *)_prefilledEmailBodyWithEmailBodyAdditions:(nullable NSDictionary *)emailBodyAdditions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's beautiful!

{
NSMutableString *prefilledEmailBodyWithEmailBodyAdditions = [NSMutableString stringWithFormat:@"%@\n", self.prefilledEmailBody];

if (emailBodyAdditions.count > 0) {
for (NSString *emailBodyAdditionKey in emailBodyAdditions.allKeys) {
[prefilledEmailBodyWithEmailBodyAdditions appendFormat:@"%@: %@\n", emailBodyAdditionKey, emailBodyAdditions[emailBodyAdditionKey]];
}
}

// Add a newline to separate prefill email body and additions from what comes after.
[prefilledEmailBodyWithEmailBodyAdditions appendString:@"\n"];

return prefilledEmailBodyWithEmailBodyAdditions;
}

- (NSString *)_recentErrorLogMessagesAsPlainText:(NSArray *)logMessages count:(NSUInteger)errorLogsToInclude;
{
NSMutableString *recentErrorLogs = [NSMutableString new];
Expand Down
33 changes: 28 additions & 5 deletions Logging/ARKLogDistributor.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ - (instancetype)init;
_logDistributingQueue.name = [NSString stringWithFormat:@"%@ Log Distributing Queue", self];
_logDistributingQueue.maxConcurrentOperationCount = 1;

#ifdef __IPHONE_8_0
if ([_logDistributingQueue respondsToSelector:@selector(setQualityOfService:)] /* iOS 8 or later */) {
_logDistributingQueue.qualityOfService = NSQualityOfServiceBackground;
}
#endif
[self _setDistributionQualityOfServiceBackground];

_logObservers = [NSMutableArray new];

Expand Down Expand Up @@ -191,8 +187,10 @@ - (void)distributeAllPendingLogsWithCompletionHandler:(dispatch_block_t)completi
{
ARKCheckCondition(completionHandler != NULL, , @"Must provide a completion handler!");

[self _setDistributionQualityOfServiceUserInitiated];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat!

[self.logDistributingQueue addOperationWithBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:completionHandler];
[self _setDistributionQualityOfServiceBackground];
}];
}

Expand Down Expand Up @@ -284,4 +282,29 @@ - (void)_logMessage_inLogDistributingQueue:(ARKLogMessage *)logMessage;
}
}

- (void)_setDistributionQualityOfServiceUserInitiated;
{
#ifdef __IPHONE_8_0
[self _setDistributionQualityOfService:NSQualityOfServiceUserInitiated];
#endif
}

- (void)_setDistributionQualityOfServiceBackground;
{
#ifdef __IPHONE_8_0
[self _setDistributionQualityOfService:NSQualityOfServiceBackground];
#endif
}

#ifdef __IPHONE_8_0

- (void)_setDistributionQualityOfService:(NSQualityOfService)qualityOfService;
{
if ([self.logDistributingQueue respondsToSelector:@selector(setQualityOfService:)] /* iOS 8 or later */) {
self.logDistributingQueue.qualityOfService = qualityOfService;
}
}

#endif

@end