@@ -32,7 +32,7 @@ @implementation GULNetworkURLSession {
32
32
#pragma clang diagnostic ignored "-Wunguarded-availability"
33
33
// / The session configuration. NSURLSessionConfiguration' is only available on iOS 7.0 or newer.
34
34
NSURLSessionConfiguration *_sessionConfig;
35
- #pragma pop
35
+ #pragma clang diagnostic pop
36
36
37
37
// / The path to the directory where all temporary files are stored before uploading.
38
38
NSURL *_networkDirectoryURL;
@@ -158,8 +158,7 @@ - (NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request
158
158
}
159
159
160
160
// Save the session into memory.
161
- NSMapTable *sessionIdentifierToFetcherMap = [[self class ] sessionIDToFetcherMap ];
162
- [sessionIdentifierToFetcherMap setObject: self forKey: _sessionID];
161
+ [self setSessionInFetcherMap: session forSessionID: _sessionID];
163
162
164
163
_request = [request copy ];
165
164
@@ -201,8 +200,7 @@ - (NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request
201
200
}
202
201
203
202
// Save the session into memory.
204
- NSMapTable *sessionIdentifierToFetcherMap = [[self class ] sessionIDToFetcherMap ];
205
- [sessionIdentifierToFetcherMap setObject: self forKey: _sessionID];
203
+ [self setSessionInFetcherMap: session forSessionID: _sessionID];
206
204
207
205
_request = [request copy ];
208
206
@@ -284,6 +282,17 @@ - (void)URLSession:(NSURLSession *)session
284
282
// Try to clean up stale files again.
285
283
[self maybeRemoveTempFilesAtURL: _networkDirectoryURL
286
284
expiringTime: kGULNetworkTempFolderExpireTime ];
285
+
286
+ // Invalidate the session only if it's owned by this class.
287
+ NSString *sessionID = session.configuration .identifier ;
288
+ if ([sessionID hasPrefix: kGULNetworkBackgroundSessionConfigIDPrefix ]) {
289
+ [session finishTasksAndInvalidate ];
290
+
291
+ // Explicitly remove the session so it won't be reused. The weak map table should
292
+ // remove the session on deallocation, but dealloc may not happen immediately after
293
+ // calling `finishTasksAndInvalidate`.
294
+ [self setSessionInFetcherMap: nil forSessionID: sessionID];
295
+ }
287
296
}
288
297
289
298
- (void )URLSession : (NSURLSession *)session
@@ -651,6 +660,28 @@ - (void)URLSession:(NSURLSession *)session
651
660
652
661
#pragma mark - Helper Methods
653
662
663
+ - (void )setSessionInFetcherMap : (NSURLSession *)session forSessionID : (NSString *)sessionID {
664
+ NSURLSession *existingSession = [self sessionFromFetcherMapForSessionID: sessionID];
665
+ if (existingSession) {
666
+ // Invalidating doesn't seem like the right thing to do here since it may cancel an active
667
+ // background transfer if the background session is handling multiple requests. The old
668
+ // session will be dropped from the map table, but still complete its request.
669
+ NSString *message = [NSString stringWithFormat: @" Discarding URL session: %@ " , existingSession];
670
+ [_loggerDelegate GULNetwork_logWithLevel: kGULNetworkLogLevelInfo
671
+ messageCode: kGULNetworkMessageCodeURLSession019
672
+ message: message];
673
+ }
674
+ if (session) {
675
+ [[[self class ] sessionIDToFetcherMap ] setObject: session forKey: sessionID];
676
+ } else {
677
+ [[[self class ] sessionIDToFetcherMap ] removeObjectForKey: sessionID];
678
+ }
679
+ }
680
+
681
+ - (nullable NSURLSession *)sessionFromFetcherMapForSessionID : (NSString *)sessionID {
682
+ return [[[self class ] sessionIDToFetcherMap ] objectForKey: sessionID];
683
+ }
684
+
654
685
- (void )callCompletionHandler : (GULNetworkURLSessionCompletionHandler)handler
655
686
withResponse : (NSHTTPURLResponse *)response
656
687
data : (NSData *)data
@@ -669,6 +700,7 @@ - (void)callCompletionHandler:(GULNetworkURLSessionCompletionHandler)handler
669
700
}
670
701
}
671
702
703
+ // Always use the request parameters even if the default session configuration is more restrictive.
672
704
- (void )populateSessionConfig : (NSURLSessionConfiguration *)sessionConfig
673
705
withRequest : (NSURLRequest *)request API_AVAILABLE(ios(7.0 )) {
674
706
sessionConfig.HTTPAdditionalHeaders = request.allHTTPHeaderFields ;
0 commit comments