Skip to content

Commit 33e820d

Browse files
Merge 976c053 into 89491ad
2 parents 89491ad + 976c053 commit 33e820d

3 files changed

Lines changed: 25 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
- Move header reference out of "extern C" (#3538)
88
- Clarify FramesTracker log message (#3570)
9+
- Fix rare battery breadcrumbs crash (#3582)
10+
911

1012
## 8.19.0
1113

Sources/Sentry/SentrySystemEventBreadcrumbs.m

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,13 @@ - (void)initBatteryObserver:(UIDevice *)currentDevice
102102
- (void)batteryStateChanged:(NSNotification *)notification
103103
{
104104
// Notifications for battery level change are sent no more frequently than once per minute
105-
NSMutableDictionary<NSString *, id> *batteryData = [self getBatteryStatus:notification.object];
106-
batteryData[@"action"] = @"BATTERY_STATE_CHANGE";
105+
UIDevice *currentDevice = notification.object;
106+
// The object of an NSNotification may be nil.
107+
if (currentDevice == nil) {
108+
return;
109+
}
110+
111+
NSDictionary<NSString *, id> *batteryData = [self getBatteryStatus:notification.object];
107112

108113
SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo
109114
category:@"device.event"];
@@ -112,7 +117,7 @@ - (void)batteryStateChanged:(NSNotification *)notification
112117
[_delegate addBreadcrumb:crumb];
113118
}
114119

115-
- (NSMutableDictionary<NSString *, id> *)getBatteryStatus:(UIDevice *)currentDevice
120+
- (NSDictionary<NSString *, id> *)getBatteryStatus:(UIDevice *)currentDevice
116121
{
117122
// borrowed and adapted from
118123
// https://github.com/apache/cordova-plugin-battery-status/blob/master/src/ios/CDVBattery.m
@@ -124,7 +129,8 @@ - (void)batteryStateChanged:(NSNotification *)notification
124129
isPlugged = YES;
125130
}
126131
float currentLevel = [currentDevice batteryLevel];
127-
NSMutableDictionary<NSString *, id> *batteryData = [NSMutableDictionary new];
132+
NSMutableDictionary<NSString *, id> *batteryData =
133+
[NSMutableDictionary dictionaryWithCapacity:3];
128134

129135
// W3C spec says level must be null if it is unknown
130136
if ((currentState != UIDeviceBatteryStateUnknown) && (currentLevel != -1.0)) {
@@ -135,6 +141,8 @@ - (void)batteryStateChanged:(NSNotification *)notification
135141
}
136142

137143
batteryData[@"plugged"] = @(isPlugged);
144+
batteryData[@"action"] = @"BATTERY_STATE_CHANGE";
145+
138146
return batteryData;
139147
}
140148

Tests/SentryTests/Integrations/Breadcrumbs/SentrySystemEventBreadcrumbsTest.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ class SentrySystemEventBreadcrumbsTest: XCTestCase {
121121
assertBatteryBreadcrumb(charging: false, level: 100)
122122
}
123123

124+
func testBatteryUIDeviceNilNotification() {
125+
let currentDevice = MyUIDevice()
126+
127+
sut = fixture.getSut(currentDevice: currentDevice)
128+
129+
postBatteryLevelNotification(uiDevice: nil)
130+
131+
expect(self.fixture.delegate.addCrumbInvocations.count) == 0
132+
}
133+
124134
private func assertBatteryBreadcrumb(charging: Bool, level: Float) {
125135

126136
XCTAssertEqual(1, fixture.delegate.addCrumbInvocations.count)
@@ -273,7 +283,7 @@ class SentrySystemEventBreadcrumbsTest: XCTestCase {
273283
XCTAssertEqual(fixture.notificationCenterWrapper.removeObserverWithNameInvocations.count, 7)
274284
}
275285

276-
private func postBatteryLevelNotification(uiDevice: UIDevice) {
286+
private func postBatteryLevelNotification(uiDevice: UIDevice?) {
277287
Dynamic(sut).batteryStateChanged(Notification(name: UIDevice.batteryLevelDidChangeNotification, object: uiDevice))
278288
}
279289

0 commit comments

Comments
 (0)