Skip to content

Commit f1eae65

Browse files
Merge 93070f9 into 62c15d4
2 parents 62c15d4 + 93070f9 commit f1eae65

File tree

2 files changed

+47
-73
lines changed

2 files changed

+47
-73
lines changed

Sources/Sentry/SentryReachability.m

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,6 @@
124124
}
125125
}
126126

127-
void
128-
SentryConnectivityReset(void)
129-
{
130-
[sentry_reachability_observers removeAllObjects];
131-
sentry_current_reachability_state = kSCNetworkReachabilityFlagsUninitialized;
132-
}
133-
134127
@implementation SentryReachability
135128

136129
+ (void)initialize
@@ -172,6 +165,10 @@ - (void)addObserver:(id<SentryReachabilityObserver>)observer;
172165

173166
sentry_reachability_queue
174167
= dispatch_queue_create("io.sentry.cocoa.connectivity", DISPATCH_QUEUE_SERIAL);
168+
// Ensure to call CFRelease for the return value of SCNetworkReachabilityCreateWithName, see
169+
// https://developer.apple.com/documentation/systemconfiguration/1514904-scnetworkreachabilitycreatewithn?language=objc
170+
// and
171+
// https://developer.apple.com/documentation/systemconfiguration/scnetworkreachability?language=objc
175172
_sentry_reachability_ref = SCNetworkReachabilityCreateWithName(NULL, "sentry.io");
176173
if (!_sentry_reachability_ref) { // Can be null if a bad hostname was specified
177174
return;
@@ -191,7 +188,9 @@ - (void)removeObserver:(id<SentryReachabilityObserver>)observer
191188
SENTRY_LOG_DEBUG(@"Synchronized to remove observer: %@", observer);
192189
[sentry_reachability_observers removeObject:observer];
193190

194-
[self unsetReachabilityCallbackIfNeeded];
191+
if (sentry_reachability_observers.count == 0) {
192+
[self unsetReachabilityCallback];
193+
}
195194
}
196195
}
197196

@@ -201,29 +200,19 @@ - (void)removeAllObservers
201200
@synchronized(sentry_reachability_observers) {
202201
SENTRY_LOG_DEBUG(@"Synchronized to remove all observers.");
203202
[sentry_reachability_observers removeAllObjects];
204-
[self unsetReachabilityCallbackIfNeeded];
203+
[self unsetReachabilityCallback];
205204
}
206205
}
207206

208-
- (void)unsetReachabilityCallbackIfNeeded
207+
- (void)unsetReachabilityCallback
209208
{
210-
if (sentry_reachability_observers.count > 0) {
211-
SENTRY_LOG_DEBUG(
212-
@"Other observers still registered, will not unset reachability callback.");
213-
return;
214-
}
215-
216-
if (!self.setReachabilityCallback) {
217-
SENTRY_LOG_DEBUG(@"Skipping unsetting reachability callback.");
218-
return;
219-
}
220-
221209
sentry_current_reachability_state = kSCNetworkReachabilityFlagsUninitialized;
222210

223211
if (_sentry_reachability_ref != nil) {
224212
SENTRY_LOG_DEBUG(@"removing callback for reachability ref %@", _sentry_reachability_ref);
225213
SCNetworkReachabilitySetCallback(_sentry_reachability_ref, NULL, NULL);
226214
SCNetworkReachabilitySetDispatchQueue(_sentry_reachability_ref, NULL);
215+
CFRelease(_sentry_reachability_ref);
227216
_sentry_reachability_ref = nil;
228217
}
229218

Tests/SentryTests/Networking/SentryReachabilityTests.m

Lines changed: 37 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,25 @@
33
#import "SentryReachability.h"
44
#import <XCTest/XCTest.h>
55

6-
void SentryConnectivityReset(void);
7-
86
@interface TestSentryReachabilityObserver : NSObject <SentryReachabilityObserver>
97

10-
@property (strong, nonatomic) XCTestExpectation *expectation;
8+
@property (assign, nonatomic) NSUInteger connectivityChangedInvocations;
119

1210
@end
1311
@implementation TestSentryReachabilityObserver
1412

15-
- (instancetype)initWithExpectation:(XCTestExpectation *)expectation
13+
- (instancetype)init
1614
{
1715
if (self = [super init]) {
18-
self.expectation = expectation;
16+
self.connectivityChangedInvocations = 0;
1917
}
2018
return self;
2119
}
2220

2321
- (void)connectivityChanged:(BOOL)connected typeDescription:(nonnull NSString *)typeDescription
2422
{
2523
NSLog(@"Received connectivity notification: %i; type: %@", connected, typeDescription);
26-
[self.expectation fulfill];
24+
self.connectivityChangedInvocations++;
2725
}
2826

2927
@end
@@ -45,8 +43,8 @@ - (void)setUp
4543

4644
- (void)tearDown
4745
{
46+
[self.reachability removeAllObservers];
4847
self.reachability = nil;
49-
SentryConnectivityReset();
5048
}
5149

5250
- (void)testConnectivityRepresentations
@@ -71,89 +69,76 @@ - (void)testConnectivityRepresentations
7169

7270
- (void)testMultipleReachabilityObservers
7371
{
74-
XCTestExpectation *aExp =
75-
[self expectationWithDescription:
76-
@"reachability state change for observer monitoring https://sentry.io"];
77-
aExp.expectedFulfillmentCount = 5;
78-
TestSentryReachabilityObserver *a =
79-
[[TestSentryReachabilityObserver alloc] initWithExpectation:aExp];
80-
[self.reachability addObserver:a];
72+
NSLog(@"[Sentry] [TEST] creating observer A");
73+
TestSentryReachabilityObserver *observerA = [[TestSentryReachabilityObserver alloc] init];
74+
NSLog(@"[Sentry] [TEST] adding observer A as reachability observer");
75+
[self.reachability addObserver:observerA];
8176

77+
NSLog(@"[Sentry] [TEST] throwaway reachability callback, setting to reachable");
8278
SentryConnectivityCallback(self.reachability.sentry_reachability_ref,
8379
kSCNetworkReachabilityFlagsReachable, nil); // ignored, as it's the first callback
80+
NSLog(@"[Sentry] [TEST] reachability callback to set to intervention required");
8481
SentryConnectivityCallback(self.reachability.sentry_reachability_ref,
8582
kSCNetworkReachabilityFlagsInterventionRequired, nil);
8683

87-
XCTestExpectation *bExp =
88-
[self expectationWithDescription:
89-
@"reachability state change for observer monitoring https://google.io"];
90-
bExp.expectedFulfillmentCount = 2;
91-
TestSentryReachabilityObserver *b =
92-
[[TestSentryReachabilityObserver alloc] initWithExpectation:bExp];
93-
[self.reachability addObserver:b];
84+
NSLog(@"[Sentry] [TEST] creating observer B");
85+
TestSentryReachabilityObserver *observerB = [[TestSentryReachabilityObserver alloc] init];
86+
NSLog(@"[Sentry] [TEST] adding observer B as reachability observer");
87+
[self.reachability addObserver:observerB];
9488

89+
NSLog(@"[Sentry] [TEST] reachability callback to set to back to reachable");
9590
SentryConnectivityCallback(
9691
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
92+
NSLog(@"[Sentry] [TEST] reachability callback to set to back to intervention required");
9793
SentryConnectivityCallback(self.reachability.sentry_reachability_ref,
9894
kSCNetworkReachabilityFlagsInterventionRequired, nil);
9995

100-
[self.reachability removeObserver:b];
96+
NSLog(@"[Sentry] [TEST] removing observer B as reachability observer");
97+
[self.reachability removeObserver:observerB];
10198

99+
NSLog(@"[Sentry] [TEST] reachability callback to set to back to reachable");
102100
SentryConnectivityCallback(
103101
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
104102

105-
[self waitForExpectations:@[ aExp, bExp ] timeout:1.0];
103+
XCTAssertEqual(5, observerA.connectivityChangedInvocations);
104+
XCTAssertEqual(2, observerB.connectivityChangedInvocations);
106105

107-
[self.reachability removeObserver:a];
106+
NSLog(@"[Sentry] [TEST] removing observer A as reachability observer");
107+
[self.reachability removeObserver:observerA];
108108
}
109109

110110
- (void)testNoObservers
111111
{
112-
XCTestExpectation *aExp =
113-
[self expectationWithDescription:
114-
@"reachability state change for observer monitoring https://sentry.io"];
115-
[aExp setInverted:YES];
116-
TestSentryReachabilityObserver *a =
117-
[[TestSentryReachabilityObserver alloc] initWithExpectation:aExp];
118-
[self.reachability addObserver:a];
119-
[self.reachability removeObserver:a];
112+
TestSentryReachabilityObserver *observer = [[TestSentryReachabilityObserver alloc] init];
113+
[self.reachability addObserver:observer];
114+
[self.reachability removeObserver:observer];
120115

121116
SentryConnectivityCallback(
122117
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
123118

124-
[self waitForExpectations:@[ aExp ] timeout:1.0];
119+
XCTAssertEqual(0, observer.connectivityChangedInvocations);
125120

126121
[self.reachability removeAllObservers];
127122
}
128123

129124
- (void)testReportSameObserver_OnlyCalledOnce
130125
{
131-
XCTestExpectation *aExp =
132-
[self expectationWithDescription:
133-
@"reachability state change for observer monitoring https://sentry.io"];
134-
aExp.expectedFulfillmentCount = 1;
135-
TestSentryReachabilityObserver *a =
136-
[[TestSentryReachabilityObserver alloc] initWithExpectation:aExp];
137-
[self.reachability addObserver:a];
138-
[self.reachability addObserver:a];
126+
TestSentryReachabilityObserver *observer = [[TestSentryReachabilityObserver alloc] init];
127+
[self.reachability addObserver:observer];
128+
[self.reachability addObserver:observer];
139129

140130
SentryConnectivityCallback(
141131
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
142132

143-
[self waitForExpectations:@[ aExp ] timeout:1.0];
133+
XCTAssertEqual(1, observer.connectivityChangedInvocations);
144134

145-
[self.reachability removeObserver:a];
135+
[self.reachability removeObserver:observer];
146136
}
147137

148138
- (void)testReportSameReachabilityState_OnlyCalledOnce
149139
{
150-
XCTestExpectation *aExp =
151-
[self expectationWithDescription:
152-
@"reachability state change for observer monitoring https://sentry.io"];
153-
aExp.expectedFulfillmentCount = 1;
154-
TestSentryReachabilityObserver *a =
155-
[[TestSentryReachabilityObserver alloc] initWithExpectation:aExp];
156-
[self.reachability addObserver:a];
140+
TestSentryReachabilityObserver *observer = [[TestSentryReachabilityObserver alloc] init];
141+
[self.reachability addObserver:observer];
157142

158143
SentryConnectivityCallback(
159144
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
@@ -162,9 +147,9 @@ - (void)testReportSameReachabilityState_OnlyCalledOnce
162147
SentryConnectivityCallback(
163148
self.reachability.sentry_reachability_ref, kSCNetworkReachabilityFlagsReachable, nil);
164149

165-
[self waitForExpectations:@[ aExp ] timeout:1.0];
150+
XCTAssertEqual(1, observer.connectivityChangedInvocations);
166151

167-
[self.reachability removeObserver:a];
152+
[self.reachability removeObserver:observer];
168153
}
169154

170155
@end

0 commit comments

Comments
 (0)