diff --git a/Libraries/CameraRoll/RCTCameraRollManager.m b/Libraries/CameraRoll/RCTCameraRollManager.m index ad84741253e..59d64cbade9 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.m +++ b/Libraries/CameraRoll/RCTCameraRollManager.m @@ -141,7 +141,7 @@ RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request inputURI = request.URL; saveBlock(); } else { - [self.bridge.imageLoader loadImageWithURLRequest:request callback:^(NSError *error, UIImage *image) { + [[self.bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:request callback:^(NSError *error, UIImage *image) { if (error) { reject(kErrorUnableToLoad, nil, error); return; diff --git a/Libraries/Image/RCTImageEditingManager.m b/Libraries/Image/RCTImageEditingManager.m index eb87df96fa7..043aab291a6 100644 --- a/Libraries/Image/RCTImageEditingManager.m +++ b/Libraries/Image/RCTImageEditingManager.m @@ -43,38 +43,39 @@ RCT_EXPORT_METHOD(cropImage:(NSURLRequest *)imageRequest [RCTConvert CGSize:cropData[@"size"]] }; - [_bridge.imageLoader loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) { - if (error) { - errorCallback(error); - return; - } + [[_bridge moduleForClass:[RCTImageLoader class]] + loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) { + if (error) { + errorCallback(error); + return; + } - // Crop image - CGSize targetSize = rect.size; - CGRect targetRect = {{-rect.origin.x, -rect.origin.y}, image.size}; - CGAffineTransform transform = RCTTransformFromTargetRect(image.size, targetRect); - UIImage *croppedImage = RCTTransformImage(image, targetSize, image.scale, transform); + // Crop image + CGSize targetSize = rect.size; + CGRect targetRect = {{-rect.origin.x, -rect.origin.y}, image.size}; + CGAffineTransform transform = RCTTransformFromTargetRect(image.size, targetRect); + UIImage *croppedImage = RCTTransformImage(image, targetSize, image.scale, transform); - // Scale image - if (cropData[@"displaySize"]) { - targetSize = [RCTConvert CGSize:cropData[@"displaySize"]]; // in pixels - RCTResizeMode resizeMode = [RCTConvert RCTResizeMode:cropData[@"resizeMode"] ?: @"contain"]; - targetRect = RCTTargetRect(croppedImage.size, targetSize, 1, resizeMode); - transform = RCTTransformFromTargetRect(croppedImage.size, targetRect); - croppedImage = RCTTransformImage(croppedImage, targetSize, image.scale, transform); - } + // Scale image + if (cropData[@"displaySize"]) { + targetSize = [RCTConvert CGSize:cropData[@"displaySize"]]; // in pixels + RCTResizeMode resizeMode = [RCTConvert RCTResizeMode:cropData[@"resizeMode"] ?: @"contain"]; + targetRect = RCTTargetRect(croppedImage.size, targetSize, 1, resizeMode); + transform = RCTTransformFromTargetRect(croppedImage.size, targetRect); + croppedImage = RCTTransformImage(croppedImage, targetSize, image.scale, transform); + } - // Store image - [self->_bridge.imageStoreManager storeImage:croppedImage withBlock:^(NSString *croppedImageTag) { - if (!croppedImageTag) { - NSString *errorMessage = @"Error storing cropped image in RCTImageStoreManager"; - RCTLogWarn(@"%@", errorMessage); - errorCallback(RCTErrorWithMessage(errorMessage)); - return; - } - successCallback(@[croppedImageTag]); - }]; - }]; + // Store image + [self->_bridge.imageStoreManager storeImage:croppedImage withBlock:^(NSString *croppedImageTag) { + if (!croppedImageTag) { + NSString *errorMessage = @"Error storing cropped image in RCTImageStoreManager"; + RCTLogWarn(@"%@", errorMessage); + errorCallback(RCTErrorWithMessage(errorMessage)); + return; + } + successCallback(@[croppedImageTag]); + }]; + }]; } @end diff --git a/Libraries/Image/RCTImageView.m b/Libraries/Image/RCTImageView.m index 7cea4625f1b..6c1c29fe407 100644 --- a/Libraries/Image/RCTImageView.m +++ b/Libraries/Image/RCTImageView.m @@ -87,7 +87,6 @@ static NSDictionary *onLoadParamsForSource(RCTImageSource *source) { if ((self = [super initWithFrame:CGRectZero])) { _bridge = bridge; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(clearImageIfDetached) @@ -328,14 +327,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) }; _reloadImageCancellationBlock = - [_bridge.imageLoader loadImageWithURLRequest:source.request - size:imageSize - scale:imageScale - clipped:NO - resizeMode:_resizeMode - progressBlock:progressHandler - partialLoadBlock:partialLoadHandler - completionBlock:completionHandler]; + [[_bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:source.request + size:imageSize + scale:imageScale + clipped:NO + resizeMode:_resizeMode + progressBlock:progressHandler + partialLoadBlock:partialLoadHandler + completionBlock:completionHandler]; } else { [self clearImage]; } diff --git a/Libraries/Image/RCTImageViewManager.m b/Libraries/Image/RCTImageViewManager.m index 7d92500f4e7..ba52d66ee6f 100644 --- a/Libraries/Image/RCTImageViewManager.m +++ b/Libraries/Image/RCTImageViewManager.m @@ -54,28 +54,30 @@ RCT_EXPORT_METHOD(getSize:(NSURLRequest *)request successBlock:(RCTResponseSenderBlock)successBlock errorBlock:(RCTResponseErrorBlock)errorBlock) { - [self.bridge.imageLoader getImageSizeForURLRequest:request - block:^(NSError *error, CGSize size) { - if (error) { - errorBlock(error); - } else { - successBlock(@[@(size.width), @(size.height)]); - } - }]; + [[self.bridge moduleForClass:[RCTImageLoader class]] + getImageSizeForURLRequest:request + block:^(NSError *error, CGSize size) { + if (error) { + errorBlock(error); + } else { + successBlock(@[@(size.width), @(size.height)]); + } + }]; } RCT_EXPORT_METHOD(getSizeWithHeaders:(RCTImageSource *)source resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - [self.bridge.imageLoader getImageSizeForURLRequest:source.request - block:^(NSError *error, CGSize size) { - if (error) { - reject(@"E_GET_SIZE_FAILURE", nil, error); - return; - } - resolve(@{@"width":@(size.width),@"height":@(size.height)}); - }]; + [[self.bridge moduleForClass:[RCTImageLoader class]] + getImageSizeForURLRequest:source.request + block:^(NSError *error, CGSize size) { + if (error) { + reject(@"E_GET_SIZE_FAILURE", nil, error); + return; + } + resolve(@{@"width":@(size.width),@"height":@(size.height)}); + }]; } RCT_EXPORT_METHOD(prefetchImage:(NSURLRequest *)request @@ -87,21 +89,22 @@ RCT_EXPORT_METHOD(prefetchImage:(NSURLRequest *)request return; } - [self.bridge.imageLoader loadImageWithURLRequest:request - callback:^(NSError *error, UIImage *image) { - if (error) { - reject(@"E_PREFETCH_FAILURE", nil, error); - return; - } - resolve(@YES); - }]; + [[self.bridge moduleForClass:[RCTImageLoader class]] + loadImageWithURLRequest:request + callback:^(NSError *error, UIImage *image) { + if (error) { + reject(@"E_PREFETCH_FAILURE", nil, error); + return; + } + resolve(@YES); + }]; } RCT_EXPORT_METHOD(queryCache:(NSArray *)requests resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - resolve([self.bridge.imageLoader getImageCacheStatus:requests]); + resolve([[self.bridge moduleForClass:[RCTImageLoader class]] getImageCacheStatus:requests]); } @end diff --git a/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m b/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m index e85c408a140..cb1718538bc 100644 --- a/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m +++ b/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m @@ -53,13 +53,20 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2) NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[loader]; } launchOptions:nil]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://facebook.github.io/react-native/img/opengraph.png"]]; - [bridge.imageLoader loadImageWithURLRequest:urlRequest size:CGSizeMake(100, 100) scale:1.0 clipped:YES resizeMode:RCTResizeModeContain progressBlock:^(int64_t progress, int64_t total) { - XCTAssertEqual(progress, 1); - XCTAssertEqual(total, 1); - } partialLoadBlock:nil completionBlock:^(NSError *loadError, id loadedImage) { - XCTAssertEqualObjects(loadedImage, image); - XCTAssertNil(loadError); - }]; + [[bridge moduleForClass:[RCTImageLoader class]] + loadImageWithURLRequest:urlRequest + size:CGSizeMake(100, 100) + scale:1.0 + clipped:YES + resizeMode:RCTResizeModeContain + progressBlock:^(int64_t progress, int64_t total) { + XCTAssertEqual(progress, 1); + XCTAssertEqual(total, 1); + } + partialLoadBlock:nil completionBlock:^(NSError *loadError, id loadedImage) { + XCTAssertEqualObjects(loadedImage, image); + XCTAssertNil(loadError); + }]; } - (void)testImageLoaderUsesImageURLLoaderWithHighestPriority @@ -84,13 +91,20 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2) NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[loader1, loader2]; } launchOptions:nil]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://facebook.github.io/react-native/img/opengraph.png"]]; - [bridge.imageLoader loadImageWithURLRequest:urlRequest size:CGSizeMake(100, 100) scale:1.0 clipped:YES resizeMode:RCTResizeModeContain progressBlock:^(int64_t progress, int64_t total) { - XCTAssertEqual(progress, 1); - XCTAssertEqual(total, 1); - } partialLoadBlock:nil completionBlock:^(NSError *loadError, id loadedImage) { - XCTAssertEqualObjects(loadedImage, image); - XCTAssertNil(loadError); - }]; + [[bridge moduleForClass:[RCTImageLoader class]] + loadImageWithURLRequest:urlRequest + size:CGSizeMake(100, 100) + scale:1.0 + clipped:YES + resizeMode:RCTResizeModeContain + progressBlock:^(int64_t progress, int64_t total) { + XCTAssertEqual(progress, 1); + XCTAssertEqual(total, 1); + } + partialLoadBlock:nil completionBlock:^(NSError *loadError, id loadedImage) { + XCTAssertEqualObjects(loadedImage, image); + XCTAssertNil(loadError); + }]; } - (void)testImageDecoding @@ -108,10 +122,17 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2) NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[decoder]; } launchOptions:nil]; - RCTImageLoaderCancellationBlock cancelBlock = [bridge.imageLoader decodeImageData:data size:CGSizeMake(1, 1) scale:1.0 clipped:NO resizeMode:RCTResizeModeStretch completionBlock:^(NSError *decodeError, id decodedImage) { + RCTImageLoaderCancellationBlock cancelBlock = + [[bridge moduleForClass:[RCTImageLoader class]] + decodeImageData:data + size:CGSizeMake(1, 1) + scale:1.0 + clipped:NO + resizeMode:RCTResizeModeStretch + completionBlock:^(NSError *decodeError, id decodedImage) { XCTAssertEqualObjects(decodedImage, image); XCTAssertNil(decodeError); - }]; + }]; XCTAssertNotNil(cancelBlock); } @@ -137,10 +158,17 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2) NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[decoder1, decoder2]; } launchOptions:nil]; - RCTImageLoaderCancellationBlock cancelBlock = [bridge.imageLoader decodeImageData:data size:CGSizeMake(1, 1) scale:1.0 clipped:NO resizeMode:RCTResizeModeStretch completionBlock:^(NSError *decodeError, id decodedImage) { - XCTAssertEqualObjects(decodedImage, image); - XCTAssertNil(decodeError); - }]; + RCTImageLoaderCancellationBlock cancelBlock = + [[bridge moduleForClass:[RCTImageLoader class]] + decodeImageData:data + size:CGSizeMake(1, 1) + scale:1.0 + clipped:NO + resizeMode:RCTResizeModeStretch + completionBlock:^(NSError *decodeError, id decodedImage) { + XCTAssertEqualObjects(decodedImage, image); + XCTAssertNil(decodeError); + }]; XCTAssertNotNil(cancelBlock); } diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index dc3963b88ad..23b5ab18670 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -251,7 +251,7 @@ using namespace facebook::react; // * `RCTImageLoader` should be moved to `RNImageComponentView`. // * `ReactNativeConfig` should be set by outside product code. _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - _contextContainer->insert("RCTImageLoader", wrapManagedObject([_bridge imageLoader])); + _contextContainer->insert("RCTImageLoader", wrapManagedObject([_bridge moduleForClass:[RCTImageLoader class]])); return _contextContainer; }