react-native-fast-image 10.8.0 → 10.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -505,7 +505,7 @@ static NSDictionary *FFFFile(NSString *path)
505
505
  - (void)clearDiskCache:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject
506
506
  {
507
507
  // And the HTTP cache of `cache: 'web'` images.
508
- [FFFastImageSource.webURLCache removeAllCachedResponses];
508
+ [FFFastImageSource clearWebURLCache];
509
509
  [SDImageCache.sharedImageCache clearDiskOnCompletion:^(){
510
510
  resolve(@{@"ok": @YES});
511
511
  }];
@@ -84,6 +84,14 @@ typedef NS_ENUM(NSInteger, FFFCacheControl) {
84
84
  // responses. 50 MB, as on Android.
85
85
  + (NSURLCache *)webURLCache;
86
86
 
87
+ // Empties webURLCache (for clearDiskCache). Its removal takes effect a few
88
+ // milliseconds after removeAllCachedResponses returns, and NSURLCache doesn't
89
+ // say when: until then a `cache: 'web'` load could still get a response from
90
+ // before the clear. So each response the web loader stores records the clear
91
+ // it came after, and for 5 s after a clear, a load ignores a cached response
92
+ // stored before it.
93
+ + (void)clearWebURLCache;
94
+
87
95
  // After a load of this source failed: for a `cache: 'web'` image whose data
88
96
  // isn't an image, removes the response from the HTTP cache, which stored it as
89
97
  // it downloaded. Otherwise the next loads would get it from there until it
@@ -215,6 +215,31 @@ static NSString *FFFBundleAssetName(NSURL *url)
215
215
  @interface FFFWebDownloaderOperation : SDWebImageDownloaderOperation
216
216
  @end
217
217
 
218
+ // The key, in a stored response's userInfo, of the clear it came after (see
219
+ // clearWebURLCache).
220
+ static NSString *const FFFCacheTokenKey = @"FFFastImageCacheToken";
221
+
222
+ // A new value at each clearWebURLCache (and one for the launch until then).
223
+ // Not the time: a change of the device's clock would move it.
224
+ static NSString *FFFWebURLCacheToken;
225
+
226
+ // When clearWebURLCache last ran, in seconds since the device started, or 0.
227
+ static NSTimeInterval FFFWebURLCacheClearedAt;
228
+
229
+ // How long after a clear loads check the response they'd get: the removal
230
+ // takes about 10 ms, longer on a busy device. Each check is a cache lookup.
231
+ static const NSTimeInterval FFFWebURLCacheClearCheck = 5;
232
+
233
+ static NSString *FFFCurrentWebURLCacheToken(void)
234
+ {
235
+ @synchronized ([FFFastImageSource class]) {
236
+ if (!FFFWebURLCacheToken) {
237
+ FFFWebURLCacheToken = NSUUID.UUID.UUIDString;
238
+ }
239
+ return FFFWebURLCacheToken;
240
+ }
241
+ }
242
+
218
243
  @implementation FFFWebDownloaderOperation
219
244
 
220
245
  // Whether data is an SVG document: its first element (after an XML
@@ -279,7 +304,14 @@ static BOOL FFFLooksLikeSVG(NSData *data)
279
304
  completionHandler(nil);
280
305
  return;
281
306
  }
282
- [super URLSession:session dataTask:dataTask willCacheResponse:proposedResponse completionHandler:completionHandler];
307
+ // The clear it came after (see clearWebURLCache).
308
+ NSMutableDictionary *userInfo = [proposedResponse.userInfo mutableCopy] ?: [NSMutableDictionary dictionary];
309
+ userInfo[FFFCacheTokenKey] = FFFCurrentWebURLCacheToken();
310
+ NSCachedURLResponse *response = [[NSCachedURLResponse alloc] initWithResponse:proposedResponse.response
311
+ data:proposedResponse.data
312
+ userInfo:userInfo
313
+ storagePolicy:proposedResponse.storagePolicy];
314
+ [super URLSession:session dataTask:dataTask willCacheResponse:response completionHandler:completionHandler];
283
315
  }
284
316
 
285
317
  @end
@@ -481,15 +513,46 @@ static BOOL FFFLooksLikeSVG(NSData *data)
481
513
  return cache;
482
514
  }
483
515
 
516
+ + (void)clearWebURLCache
517
+ {
518
+ @synchronized (self) {
519
+ FFFWebURLCacheToken = NSUUID.UUID.UUIDString;
520
+ FFFWebURLCacheClearedAt = NSProcessInfo.processInfo.systemUptime;
521
+ }
522
+ [self.webURLCache removeAllCachedResponses];
523
+ }
524
+
525
+ // Whether the HTTP cache's response to the request was stored before the last
526
+ // clearWebURLCache (or has no token: stored by an app's own operation class),
527
+ // in the few seconds after it.
528
+ + (BOOL)isCachedBeforeClear:(NSURLRequest *)request
529
+ {
530
+ NSString *token;
531
+ NSTimeInterval clearedAt;
532
+ @synchronized (self) {
533
+ token = FFFWebURLCacheToken;
534
+ clearedAt = FFFWebURLCacheClearedAt;
535
+ }
536
+ if (clearedAt == 0 || NSProcessInfo.processInfo.systemUptime - clearedAt > FFFWebURLCacheClearCheck) {
537
+ return NO;
538
+ }
539
+ NSCachedURLResponse *cached = [self.webURLCache cachedResponseForRequest:request];
540
+ return cached && ![cached.userInfo[FFFCacheTokenKey] isEqual:token];
541
+ }
542
+
484
543
  - (SDWebImageDownloaderRequestModifier *)requestModifier
485
544
  {
486
545
  NSDictionary* headers = _headers;
546
+ BOOL web = _cacheControl == FFFCacheControlWeb;
487
547
  return [SDWebImageDownloaderRequestModifier requestModifierWithBlock: ^NSURLRequest* _Nullable (NSURLRequest* _Nonnull request) {
488
548
  NSMutableURLRequest* mutableRequest = [request mutableCopy];
489
549
  for (NSString* header in headers) {
490
550
  NSString* value = headers[header];
491
551
  [mutableRequest setValue: value forHTTPHeaderField: header];
492
552
  }
553
+ if (web && [FFFastImageSource isCachedBeforeClear:mutableRequest]) {
554
+ mutableRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
555
+ }
493
556
  return [mutableRequest copy];
494
557
  }];
495
558
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "10.8.0",
3
+ "version": "10.8.1",
4
4
  "description": "FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",