react-native-fast-image 8.6.41 → 8.6.42

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.
@@ -1,6 +1,7 @@
1
1
  #import "FFFastImageView.h"
2
2
  #import <SDWebImage/UIImage+MultiFormat.h>
3
3
  #import <SDWebImage/UIView+WebCache.h>
4
+ #import <React/RCTUtils.h>
4
5
 
5
6
  @interface FFFastImageView ()
6
7
 
@@ -14,11 +15,31 @@
14
15
  // The image before tinting, kept while a tint is applied so the tint can be
15
16
  // changed or removed. nil when there's no tint (super.image is untinted).
16
17
  @property(nonatomic, strong) UIImage* untintedImage;
18
+ // Whether the current load was already restarted after the app came back
19
+ // from the background (see downloadImage:).
20
+ @property(nonatomic, assign) BOOL retriedAfterBackground;
21
+ // Waits for the app to be active again, to restart a load.
22
+ @property(nonatomic, strong) id activeObserver;
17
23
 
18
24
  @end
19
25
 
26
+ // When the app last went to the background (CACurrentMediaTime), or 0.
27
+ static CFTimeInterval FFFEnteredBackgroundAt = 0;
28
+
20
29
  @implementation FFFastImageView
21
30
 
31
+ + (void) initialize {
32
+ if (self != [FFFastImageView class]) {
33
+ return;
34
+ }
35
+ [[NSNotificationCenter defaultCenter] addObserverForName: UIApplicationDidEnterBackgroundNotification
36
+ object: nil
37
+ queue: [NSOperationQueue mainQueue]
38
+ usingBlock: ^(NSNotification* notification) {
39
+ FFFEnteredBackgroundAt = CACurrentMediaTime();
40
+ }];
41
+ }
42
+
22
43
  - (id) init {
23
44
  self = [super init];
24
45
  self.resizeMode = RCTResizeModeCover;
@@ -232,6 +253,8 @@
232
253
  }
233
254
  self.hasCompleted = NO;
234
255
  self.hasErrored = NO;
256
+ self.retriedAfterBackground = NO;
257
+ [self stopWaitingForActive];
235
258
 
236
259
  [self downloadImage: _source options: options context: context];
237
260
  } else if (_defaultSource) {
@@ -267,6 +290,7 @@
267
290
  });
268
291
  };
269
292
  }
293
+ CFTimeInterval startedAt = CACurrentMediaTime();
270
294
  [self sd_setImageWithURL: _source.url
271
295
  placeholderImage: _defaultSource
272
296
  options: options
@@ -276,6 +300,18 @@
276
300
  NSError* _Nullable error,
277
301
  SDImageCacheType cacheType,
278
302
  NSURL* _Nullable imageURL) {
303
+ // The download was running when the app went to the
304
+ // background, and failed: iOS suspends it there, and its
305
+ // timeout keeps counting, so it times out as the app comes
306
+ // back (NSURLErrorTimedOut), or loses its connection. Load it
307
+ // again once the app is active, as Android does (#758).
308
+ if (error && [error.domain isEqualToString: NSURLErrorDomain] &&
309
+ FFFEnteredBackgroundAt > startedAt && !weakSelf.retriedAfterBackground &&
310
+ weakSelf.source == source) {
311
+ weakSelf.retriedAfterBackground = YES;
312
+ [weakSelf downloadWhenActive: source options: options context: context];
313
+ return;
314
+ }
279
315
  if (error) {
280
316
  weakSelf.hasErrored = YES;
281
317
  if (weakSelf.onFastImageError) {
@@ -294,7 +330,37 @@
294
330
  }];
295
331
  }
296
332
 
333
+ // Downloads the source now if the app is active, or once it is (unless
334
+ // another load started meanwhile).
335
+ - (void) downloadWhenActive: (FFFastImageSource*)source options: (SDWebImageOptions)options context: (SDWebImageContext*)context {
336
+ // nil in app extensions, which don't get these notifications.
337
+ UIApplication* application = RCTSharedApplication();
338
+ if (!application || application.applicationState == UIApplicationStateActive) {
339
+ [self downloadImage: source options: options context: context];
340
+ return;
341
+ }
342
+ [self stopWaitingForActive];
343
+ __weak typeof(self) weakSelf = self;
344
+ self.activeObserver = [[NSNotificationCenter defaultCenter] addObserverForName: UIApplicationDidBecomeActiveNotification
345
+ object: nil
346
+ queue: [NSOperationQueue mainQueue]
347
+ usingBlock: ^(NSNotification* notification) {
348
+ [weakSelf stopWaitingForActive];
349
+ if (weakSelf.source == source) {
350
+ [weakSelf downloadImage: source options: options context: context];
351
+ }
352
+ }];
353
+ }
354
+
355
+ - (void) stopWaitingForActive {
356
+ if (self.activeObserver) {
357
+ [[NSNotificationCenter defaultCenter] removeObserver: self.activeObserver];
358
+ self.activeObserver = nil;
359
+ }
360
+ }
361
+
297
362
  - (void) dealloc {
363
+ [self stopWaitingForActive];
298
364
  [self sd_cancelCurrentImageLoad];
299
365
  }
300
366
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "8.6.41",
3
+ "version": "8.6.42",
4
4
  "description": "🚩 FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",