Skip to content

Commit

Permalink
Remove "completed" flag from reporting API (#553)
Browse files Browse the repository at this point in the history
* Remove "completed" bool flag in reporting

* Update tests

* Fix format

* Fix alert logic

* Add "log with alert" to sample

* Remove obsolete docs
  • Loading branch information
bamx23 committed Sep 3, 2024
1 parent e680dd9 commit a96174d
Show file tree
Hide file tree
Showing 24 changed files with 162 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class DirectorySink: NSObject, CrashReportFilter {
self.directoryUrl = directoryUrl
}

public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, Bool, (any Error)?) -> Void)? = nil) {
public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, (any Error)?) -> Void)? = nil) {
let prefix = UUID().uuidString
for (idx, report) in reports.enumerated() {
let fileName = "\(prefix)-\(idx).ips"
Expand All @@ -82,6 +82,6 @@ public class DirectorySink: NSObject, CrashReportFilter {
Self.logger.error("Failed to save report: \(error)")
}
}
onCompletion?(reports, true, nil)
onCompletion?(reports, nil)
}
}
26 changes: 16 additions & 10 deletions Samples/Common/Sources/LibraryBridge/CrashReportStore+Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ public extension CrashReportStore {
private static let logger = Logger(label: "ReportingSample")

func logAll() async throws {
let (reports, isSuccess) = try await sendAllReports()
guard isSuccess else {
return
}
let reports = try await sendAllReports()
for report in reports {
guard let report = report as? CrashReportDictionary else {
continue
Expand All @@ -49,8 +46,8 @@ public extension CrashReportStore {

func logToConsole() {
sink = CrashReportSinkConsole.filter().defaultCrashReportFilterSet()
sendAllReports { reports, isSuccess, error in
if isSuccess, let reports {
sendAllReports { reports, error in
if let reports {
Self.logger.info("Logged \(reports.count) reports")
for (idx, report) in reports.enumerated() {
switch report {
Expand All @@ -70,6 +67,15 @@ public extension CrashReportStore {
}
}

func logWithAlert() {
sink = CrashReportFilterPipeline(filtersArray: [
CrashReportFilterAlert(title: "Sample Alert", message: "Do you want to log?", yesAnswer: "Yes", noAnswer: "No"),
CrashReportFilterAppleFmt(),
CrashReportSinkConsole(),
])
sendAllReports()
}

func sampleLogToConsole() {
sink = CrashReportFilterPipeline(filtersArray: [
CrashReportFilterDemangle(),
Expand Down Expand Up @@ -123,21 +129,21 @@ public class SampleCrashReport: NSObject, CrashReport {
}

public class SampleFilter: NSObject, CrashReportFilter {
public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, Bool, (any Error)?) -> Void)? = nil) {
public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, (any Error)?) -> Void)? = nil) {
let filtered = reports.compactMap { report -> SampleCrashReport? in
guard let dictReport = report as? CrashReportDictionary else {
return nil
}
return SampleCrashReport(dictReport)
}
onCompletion?(filtered, true, nil)
onCompletion?(filtered, nil)
}
}

public class SampleSink: NSObject, CrashReportFilter {
private static let logger = Logger(label: "SampleSink")

public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, Bool, (any Error)?) -> Void)? = nil) {
public func filterReports(_ reports: [any CrashReport], onCompletion: (([any CrashReport]?, (any Error)?) -> Void)? = nil) {
for (idx, report) in reports.enumerated() {
guard let sampleReport = report as? SampleCrashReport else {
continue
Expand All @@ -149,6 +155,6 @@ public class SampleSink: NSObject, CrashReportFilter {
let text = lines.joined(separator: "\n")
Self.logger.info("\(text)")
}
onCompletion?(reports, true, nil)
onCompletion?(reports, nil)
}
}
3 changes: 3 additions & 0 deletions Samples/Common/Sources/SampleUI/Screens/ReportingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ struct ReportingView: View {
Button("Sample Custom Log To Console") {
store.sampleLogToConsole()
}
Button("Log with Alert") {
store.logWithAlert()
}
}
.navigationTitle("Report")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
[filteredReports addObject:[KSCrashReportDictionary reportWithValue:reportDict]];
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
46 changes: 26 additions & 20 deletions Sources/KSCrashFilters/KSCrashReportFilterAlert.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#import "KSCrashReportFilterAlert.h"

#import "KSCrashReport.h"
#import "KSNSErrorHelper.h"
#import "KSSystemCapabilities.h"

// #define KSLogger_LocalLevel TRACE
Expand Down Expand Up @@ -82,18 +83,17 @@ - (void)startWithTitle:(NSString *)title
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *yesAction =
[UIAlertAction actionWithTitle:yesAnswer
style:UIAlertActionStyleDefault
handler:^(__unused UIAlertAction *_Nonnull action) {
kscrash_callCompletion(self.onCompletion, self.reports, YES, nil);
}];
UIAlertAction *noAction =
[UIAlertAction actionWithTitle:noAnswer
style:UIAlertActionStyleCancel
handler:^(__unused UIAlertAction *_Nonnull action) {
kscrash_callCompletion(self.onCompletion, self.reports, NO, nil);
}];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:yesAnswer
style:UIAlertActionStyleDefault
handler:^(__unused UIAlertAction *_Nonnull action) {
kscrash_callCompletion(self.onCompletion, self.reports, nil);
}];
UIAlertAction *noAction = [UIAlertAction
actionWithTitle:noAnswer
style:UIAlertActionStyleCancel
handler:^(__unused UIAlertAction *_Nonnull action) {
kscrash_callCompletion(self.onCompletion, self.reports, [[self class] cancellationError]);
}];
[alertController addAction:yesAction];
[alertController addAction:noAction];
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
Expand All @@ -108,18 +108,24 @@ - (void)startWithTitle:(NSString *)title
[alert setInformativeText:message];
[alert setAlertStyle:NSAlertStyleInformational];

BOOL success = NO;
if ([alert runModal] == NSAlertFirstButtonReturn) {
success = noAnswer != nil;
NSModalResponse response = [alert runModal];
NSError *error = nil;
if (noAnswer != nil && response == NSAlertSecondButtonReturn) {
error = [[self class] cancellationError];
}
kscrash_callCompletion(self.onCompletion, self.reports, success, nil);
kscrash_callCompletion(self.onCompletion, self.reports, error);
#endif
}

+ (NSError *)cancellationError
{
return [KSNSErrorHelper errorWithDomain:[[self class] description] code:0 description:@"Cancelled by user"];
}

- (void)alertView:(__unused id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
BOOL success = buttonIndex == self.expectedButtonIndex;
kscrash_callCompletion(self.onCompletion, self.reports, success, nil);
kscrash_callCompletion(self.onCompletion, self.reports, success ? nil : [[self class] cancellationError]);
}

@end
Expand Down Expand Up @@ -167,9 +173,9 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
yesAnswer:self.yesAnswer
noAnswer:self.noAnswer
reports:reports
onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) {
onCompletion:^(NSArray *filteredReports, NSError *error) {
KSLOG_TRACE(@"alert process complete");
kscrash_callCompletion(onCompletion, filteredReports, completed, error);
kscrash_callCompletion(onCompletion, filteredReports, error);
dispatch_async(dispatch_get_main_queue(), ^{
process = nil;
});
Expand Down Expand Up @@ -205,7 +211,7 @@ - (id)initWithTitle:(__unused NSString *)title
- (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion
{
KSLOG_WARN(@"Alert filter not available on this platform.");
kscrash_callCompletion(onCompletion, reports, YES, nil);
kscrash_callCompletion(onCompletion, reports, nil);
}

@end
Expand Down
2 changes: 1 addition & 1 deletion Sources/KSCrashFilters/KSCrashReportFilterAppleFmt.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
}
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

- (NSString *)CPUType:(NSString *)CPUArch isSystemInfoHeader:(BOOL)isSystemInfoHeader
Expand Down
44 changes: 22 additions & 22 deletions Sources/KSCrashFilters/KSCrashReportFilterBasic.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ + (instancetype)filter

- (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion
{
kscrash_callCompletion(onCompletion, reports, YES, nil);
kscrash_callCompletion(onCompletion, reports, nil);
}

@end
Expand Down Expand Up @@ -120,13 +120,13 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
NSUInteger filterCount = [filters count];

if (filterCount == 0) {
kscrash_callCompletion(onCompletion, reports, YES, nil);
kscrash_callCompletion(onCompletion, reports, nil);
return;
}

if (filterCount != [keys count]) {
kscrash_callCompletion(
onCompletion, reports, NO,
onCompletion, reports,
[KSNSErrorHelper errorWithDomain:[[self class] description]
code:0
description:@"Key/filter mismatch (%d keys, %d filters", [keys count], filterCount]);
Expand All @@ -144,12 +144,12 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
filterCompletion = nil;
});
} copy];
filterCompletion = [^(NSArray<id<KSCrashReport>> *filteredReports, BOOL completed, NSError *filterError) {
if (!completed || filteredReports == nil) {
if (!completed) {
kscrash_callCompletion(onCompletion, filteredReports, completed, filterError);
filterCompletion = [^(NSArray<id<KSCrashReport>> *filteredReports, NSError *filterError) {
if (filterError != nil || filteredReports == nil) {
if (filterError != nil) {
kscrash_callCompletion(onCompletion, filteredReports, filterError);
} else if (filteredReports == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO,
kscrash_callCompletion(onCompletion, filteredReports,
[KSNSErrorHelper errorWithDomain:[[self class] description]
code:0
description:@"filteredReports was nil"]);
Expand Down Expand Up @@ -184,7 +184,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
[combinedReports addObject:report];
}

kscrash_callCompletion(onCompletion, combinedReports, completed, filterError);
kscrash_callCompletion(onCompletion, combinedReports, filterError);
disposeOfCompletion();
} copy];
weakFilterCompletion = filterCompletion;
Expand Down Expand Up @@ -248,7 +248,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
NSUInteger filterCount = [filters count];

if (filterCount == 0) {
kscrash_callCompletion(onCompletion, reports, YES, nil);
kscrash_callCompletion(onCompletion, reports, nil);
return;
}

Expand All @@ -261,12 +261,12 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
filterCompletion = nil;
});
} copy];
filterCompletion = [^(NSArray<id<KSCrashReport>> *filteredReports, BOOL completed, NSError *filterError) {
if (!completed || filteredReports == nil) {
if (!completed) {
kscrash_callCompletion(onCompletion, filteredReports, completed, filterError);
filterCompletion = [^(NSArray<id<KSCrashReport>> *filteredReports, NSError *filterError) {
if (filterError != nil || filteredReports == nil) {
if (filterError != nil) {
kscrash_callCompletion(onCompletion, filteredReports, filterError);
} else if (filteredReports == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO,
kscrash_callCompletion(onCompletion, filteredReports,
[KSNSErrorHelper errorWithDomain:[[self class] description]
code:0
description:@"filteredReports was nil"]);
Expand All @@ -284,7 +284,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
}

// All filters complete, or a filter failed.
kscrash_callCompletion(onCompletion, filteredReports, completed, filterError);
kscrash_callCompletion(onCompletion, filteredReports, filterError);
disposeOfCompletion();
} copy];
weakFilterCompletion = filterCompletion;
Expand Down Expand Up @@ -361,7 +361,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
}
[filteredReports addObject:concatenated];
}
kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
Expand Down Expand Up @@ -421,7 +421,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
for (NSString *keyPath in self.keyPaths) {
id object = [KSNSDictionaryHelper objectInDictionary:report.value forKeyPath:keyPath];
if (object == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO,
kscrash_callCompletion(onCompletion, filteredReports,
[KSNSErrorHelper errorWithDomain:[[self class] description]
code:0
description:@"Report did not have key path %@", keyPath]);
Expand All @@ -432,7 +432,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
id<KSCrashReport> subsetReport = [KSCrashReportDictionary reportWithValue:subset];
[filteredReports addObject:subsetReport];
}
kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
Expand Down Expand Up @@ -461,7 +461,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
[filteredReports addObject:[KSCrashReportString reportWithValue:converted]];
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
Expand All @@ -484,7 +484,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras

NSData *converted = [report.value dataUsingEncoding:NSUTF8StringEncoding];
if (converted == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO,
kscrash_callCompletion(onCompletion, filteredReports,
[KSNSErrorHelper errorWithDomain:[[self class] description]
code:0
description:@"Could not convert report to UTF-8"]);
Expand All @@ -494,7 +494,7 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
}
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
8 changes: 4 additions & 4 deletions Sources/KSCrashFilters/KSCrashReportFilterGZip.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
compressionLevel:(int)self.compressionLevel
error:&error];
if (compressedData == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO, error);
kscrash_callCompletion(onCompletion, filteredReports, error);
return;
} else {
[filteredReports addObject:[KSCrashReportData reportWithValue:compressedData]];
}
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
Expand All @@ -97,14 +97,14 @@ - (void)filterReports:(NSArray<id<KSCrashReport>> *)reports onCompletion:(KSCras
NSError *error = nil;
NSData *decompressedData = [KSGZipHelper gunzippedData:report.value error:&error];
if (decompressedData == nil) {
kscrash_callCompletion(onCompletion, filteredReports, NO, error);
kscrash_callCompletion(onCompletion, filteredReports, error);
return;
} else {
[filteredReports addObject:[KSCrashReportData reportWithValue:decompressedData]];
}
}

kscrash_callCompletion(onCompletion, filteredReports, YES, nil);
kscrash_callCompletion(onCompletion, filteredReports, nil);
}

@end
Loading

0 comments on commit a96174d

Please sign in to comment.