-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introducing RCTBlockingImageManager, an image manager for tests in Fa…
…bric Summary: Changelog: [Internal] This allows to block queue until image is fetched. In paper, the photo of dog will not appear unless the network request is "fast enough". {F228670428} Reviewed By: shergin Differential Revision: D19907906 fbshipit-source-id: 98d68abf1255388f9b97fb9da367d8f583a4220d
- Loading branch information
1 parent
b53aeab
commit aa0a50c
Showing
5 changed files
with
150 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
ReactCommon/fabric/imagemanager/platform/ios/RCTImageManagerProtocol.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import <Foundation/Foundation.h> | ||
#import <react/core/ReactPrimitives.h> | ||
#import <react/imagemanager/ImageRequest.h> | ||
|
||
@protocol RCTImageManagerProtocol <NSObject> | ||
|
||
- (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource | ||
surfaceId:(facebook::react::SurfaceId)surfaceId; | ||
@end |
28 changes: 28 additions & 0 deletions
28
ReactCommon/fabric/imagemanager/platform/ios/RCTSyncImageManager.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
#import <RCTImageManagerProtocol.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@protocol RCTImageLoaderWithAttributionProtocol; | ||
|
||
/** | ||
* iOS-specific ImageManager. | ||
*/ | ||
@interface RCTSyncImageManager : NSObject <RCTImageManagerProtocol> | ||
|
||
- (instancetype)initWithImageLoader:(id<RCTImageLoaderWithAttributionProtocol>)imageLoader; | ||
|
||
- (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource | ||
surfaceId:(facebook::react::SurfaceId)surfaceId; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
97 changes: 97 additions & 0 deletions
97
ReactCommon/fabric/imagemanager/platform/ios/RCTSyncImageManager.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import "RCTSyncImageManager.h" | ||
|
||
#import <react/utils/ManagedObjectWrapper.h> | ||
#import <react/utils/SharedFunction.h> | ||
|
||
#import <React/RCTAssert.h> | ||
#import <React/RCTImageLoaderWithAttributionProtocol.h> | ||
#import <React/RCTLog.h> | ||
#import <react/imagemanager/ImageResponse.h> | ||
#import <react/imagemanager/ImageResponseObserver.h> | ||
|
||
#import "RCTImagePrimitivesConversions.h" | ||
|
||
using namespace facebook::react; | ||
|
||
@implementation RCTSyncImageManager { | ||
id<RCTImageLoaderWithAttributionProtocol> _imageLoader; | ||
} | ||
|
||
- (instancetype)initWithImageLoader:(id<RCTImageLoaderWithAttributionProtocol>)imageLoader | ||
{ | ||
if (self = [super init]) { | ||
RCTAssert(RCTRunningInTestEnvironment(), @"This class is only meant to be used in test environment"); | ||
_imageLoader = imageLoader; | ||
} | ||
|
||
return self; | ||
} | ||
|
||
- (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfaceId | ||
{ | ||
auto imageRequest = ImageRequest(imageSource, nullptr); | ||
auto weakObserverCoordinator = | ||
(std::weak_ptr<const ImageResponseObserverCoordinator>)imageRequest.getSharedObserverCoordinator(); | ||
|
||
auto sharedCancelationFunction = SharedFunction<>(); | ||
imageRequest.setCancelationFunction(sharedCancelationFunction); | ||
|
||
dispatch_group_t imageWaitGroup = dispatch_group_create(); | ||
|
||
dispatch_group_enter(imageWaitGroup); | ||
|
||
NSURLRequest *request = NSURLRequestFromImageSource(imageSource); | ||
|
||
auto completionBlock = ^(NSError *error, UIImage *image) { | ||
auto observerCoordinator = weakObserverCoordinator.lock(); | ||
if (!observerCoordinator) { | ||
return; | ||
} | ||
|
||
if (image && !error) { | ||
observerCoordinator->nativeImageResponseComplete(ImageResponse(wrapManagedObject(image))); | ||
} else { | ||
observerCoordinator->nativeImageResponseFailed(); | ||
} | ||
dispatch_group_leave(imageWaitGroup); | ||
}; | ||
|
||
auto progressBlock = ^(int64_t progress, int64_t total) { | ||
auto observerCoordinator = weakObserverCoordinator.lock(); | ||
if (!observerCoordinator) { | ||
return; | ||
} | ||
|
||
observerCoordinator->nativeImageResponseProgress(progress / (float)total); | ||
}; | ||
|
||
RCTImageURLLoaderRequest *loaderRequest = | ||
[self->_imageLoader loadImageWithURLRequest:request | ||
size:CGSizeMake(imageSource.size.width, imageSource.size.height) | ||
scale:imageSource.scale | ||
clipped:YES | ||
resizeMode:RCTResizeModeStretch | ||
attribution:{ | ||
.surfaceId = surfaceId, | ||
} | ||
progressBlock:progressBlock | ||
partialLoadBlock:nil | ||
completionBlock:completionBlock]; | ||
RCTImageLoaderCancellationBlock cancelationBlock = loaderRequest.cancellationBlock; | ||
sharedCancelationFunction.assign([cancelationBlock]() { cancelationBlock(); }); | ||
|
||
auto result = dispatch_group_wait(imageWaitGroup, dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC)); | ||
if (result != 0) { | ||
RCTLogError(@"Getting an image timed out"); | ||
} | ||
return imageRequest; | ||
} | ||
|
||
@end |