Skip to content

Commit f8758eb

Browse files
authored
Fix a crash that happens when the application changes states. (#14102)
1 parent 33f8419 commit f8758eb

File tree

4 files changed

+71
-26
lines changed

4 files changed

+71
-26
lines changed

FirebasePerformance/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Unreleased
2+
- [fixed] Fix a crash related to registering for notifications when the app is between foreground or background states. (#13174)
3+
14
# 11.5.0
25
- [fixed] Replaced usage of the deprecated `UIApplication.keyWindow` property
36
with `UIWindow.isKeyWindow`; this API is also available on visionOS. Note that

FirebasePerformance/Sources/AppActivity/FPRTraceBackgroundActivityTracker.m

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ - (instancetype)init {
3535
} else {
3636
_traceBackgroundState = FPRTraceStateForegroundOnly;
3737
}
38+
dispatch_async(dispatch_get_main_queue(), ^{
39+
[[NSNotificationCenter defaultCenter] addObserver:self
40+
selector:@selector(applicationDidBecomeActive:)
41+
name:UIApplicationDidBecomeActiveNotification
42+
object:[UIApplication sharedApplication]];
3843

39-
[[NSNotificationCenter defaultCenter] addObserver:self
40-
selector:@selector(applicationDidBecomeActive:)
41-
name:UIApplicationDidBecomeActiveNotification
42-
object:[UIApplication sharedApplication]];
43-
44-
[[NSNotificationCenter defaultCenter] addObserver:self
45-
selector:@selector(applicationDidEnterBackground:)
46-
name:UIApplicationDidEnterBackgroundNotification
47-
object:[UIApplication sharedApplication]];
44+
[[NSNotificationCenter defaultCenter] addObserver:self
45+
selector:@selector(applicationDidEnterBackground:)
46+
name:UIApplicationDidEnterBackgroundNotification
47+
object:[UIApplication sharedApplication]];
48+
});
4849
}
4950
return self;
5051
}

FirebasePerformance/Tests/Unit/FPRTraceBackgroundActivityTrackerTest.m

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,27 @@ - (void)testForegroundTracking {
3838

3939
/** Validates if the foreground & background state is captured correctly. */
4040
- (void)testBackgroundTracking {
41+
XCTestExpectation *expectation = [self expectationWithDescription:@"Application state change"];
42+
4143
FPRTraceBackgroundActivityTracker *tracker = [[FPRTraceBackgroundActivityTracker alloc] init];
4244
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
43-
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
44-
object:[UIApplication sharedApplication]];
45-
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
46-
object:[UIApplication sharedApplication]];
47-
XCTAssertEqual(tracker.traceBackgroundState, FPRTraceStateBackgroundAndForeground);
45+
dispatch_async(dispatch_get_main_queue(), ^{
46+
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
47+
object:[UIApplication sharedApplication]];
48+
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
49+
object:[UIApplication sharedApplication]];
50+
[expectation fulfill];
51+
});
52+
53+
[self waitForExpectationsWithTimeout:5.0
54+
handler:^(NSError *_Nullable error) {
55+
if (error) {
56+
XCTFail(@"Expectation failed with error: %@", error);
57+
} else {
58+
XCTAssertEqual(tracker.traceBackgroundState,
59+
FPRTraceStateBackgroundAndForeground);
60+
}
61+
}];
4862
}
4963

5064
@end

FirebasePerformance/Tests/Unit/Timer/FIRTraceTest.m

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -427,15 +427,28 @@ - (void)testValidTraceWithStageAndMetrics {
427427

428428
/** Validates the value of background state when the app is backgrounded. */
429429
- (void)testValidTraceWithBackgrounding {
430+
XCTestExpectation *expectation = [self expectationWithDescription:@"Application state change"];
430431
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
431432
FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
432433
[trace start];
433-
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
434-
object:[UIApplication sharedApplication]];
435-
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
436-
object:[UIApplication sharedApplication]];
437-
XCTAssertEqual(trace.backgroundTraceState, FPRTraceStateBackgroundAndForeground);
438-
[trace stop];
434+
dispatch_async(dispatch_get_main_queue(), ^{
435+
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
436+
object:[UIApplication sharedApplication]];
437+
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
438+
object:[UIApplication sharedApplication]];
439+
[expectation fulfill];
440+
});
441+
442+
[self waitForExpectationsWithTimeout:5.0
443+
handler:^(NSError *_Nullable error) {
444+
if (error) {
445+
XCTFail(@"Expectation failed with error: %@", error);
446+
} else {
447+
XCTAssertEqual(trace.backgroundTraceState,
448+
FPRTraceStateBackgroundAndForeground);
449+
[trace stop];
450+
}
451+
}];
439452
}
440453

441454
/** Validates the value of background state when trace is not started. */
@@ -452,15 +465,29 @@ - (void)testValidTraceWithoutStart {
452465

453466
/** Validates the value of background state is available after trace is stopped. */
454467
- (void)testBackgroundStateAfterTraceStop {
468+
XCTestExpectation *expectation = [self expectationWithDescription:@"Application state change"];
469+
455470
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
456471
FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
457472
[trace start];
458-
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
459-
object:[UIApplication sharedApplication]];
460-
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
461-
object:[UIApplication sharedApplication]];
462-
[trace stop];
463-
XCTAssertEqual(trace.backgroundTraceState, FPRTraceStateBackgroundAndForeground);
473+
dispatch_async(dispatch_get_main_queue(), ^{
474+
[defaultCenter postNotificationName:UIApplicationDidEnterBackgroundNotification
475+
object:[UIApplication sharedApplication]];
476+
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
477+
object:[UIApplication sharedApplication]];
478+
[expectation fulfill];
479+
});
480+
481+
[self waitForExpectationsWithTimeout:5.0
482+
handler:^(NSError *_Nullable error) {
483+
if (error) {
484+
XCTFail(@"Expectation failed with error: %@", error);
485+
} else {
486+
[trace stop];
487+
XCTAssertEqual(trace.backgroundTraceState,
488+
FPRTraceStateBackgroundAndForeground);
489+
}
490+
}];
464491
}
465492

466493
/** Validates that stages do not have any valid background state. */

0 commit comments

Comments
 (0)