diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index a391f5b9b56..0a6031a9141 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -768,6 +768,16 @@ RCT_ENUM_CONVERTER(RCTAnimationType, (@{ NSString *scheme = URL.scheme.lowercaseString; if ([scheme isEqualToString:@"file"]) { image = RCTImageFromLocalAssetURL(URL); + // There is a case where this may fail when the image is at the bundle location. + // RCTImageFromLocalAssetURL only checks for the image in the same location as the jsbundle + // Hence, if the bundle is CodePush-ed, it will not be able to find the image. + // This check is added here instead of being inside RCTImageFromLocalAssetURL, since + // we don't want breaking changes to RCTImageFromLocalAssetURL, which is called in a lot of places + // This is a deprecated method, and hence has the least impact on existing code. Basically, + // instead of crashing the app, it tries one more location for the image. + if (!image) { + image = RCTImageFromLocalBundleAssetURL(URL); + } if (!image) { RCTLogConvertError(json, @"an image. File not found."); } diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index cd6166d5221..8b2b4063dfb 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -133,6 +133,11 @@ RCT_EXTERN BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL); // does not correspond to a local asset. RCT_EXTERN UIImage *__nullable RCTImageFromLocalAssetURL(NSURL *imageURL); +// Only used in case when RCTImageFromLocalAssetURL fails to get an image +// This method basically checks for the image in the bundle location, instead +// of the CodePush location +RCT_EXTERN UIImage *__nullable RCTImageFromLocalBundleAssetURL(NSURL *imageURL); + // Creates a new, unique temporary file path with the specified extension RCT_EXTERN NSString *__nullable RCTTempFilePath(NSString *__nullable extension, NSError **error); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index 614457e1a9c..c996c5f1328 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -716,6 +716,19 @@ static NSBundle *bundleForPath(NSString *key) return bundleCache[key]; } +UIImage *__nullable RCTImageFromLocalBundleAssetURL(NSURL *imageURL) +{ + if (![imageURL.scheme isEqualToString:@"file"]) { + // We only want to check for local file assets + return nil; + } + // Get the bundle URL, and add the image URL + // Note that we have to add both host and path, since host is the first "assets" part + // while path is the rest of the URL + NSURL *bundleImageUrl = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:[imageURL.host stringByAppendingString:imageURL.path]]; + return RCTImageFromLocalAssetURL(bundleImageUrl); +} + UIImage *__nullable RCTImageFromLocalAssetURL(NSURL *imageURL) { NSString *imageName = RCTBundlePathForURL(imageURL);