From 2fecbf61711f610124fc2453a79120932024f613 Mon Sep 17 00:00:00 2001 From: Yujie Liu Date: Thu, 14 Dec 2017 14:23:35 -0800 Subject: [PATCH] Add RCTLibraryPathForURL in RCTUtil Reviewed By: fromcelticpark Differential Revision: D6445626 fbshipit-source-id: aa37c87f019eea85d76365b6be919adfafc3c27a --- Libraries/Network/RCTFileRequestHandler.m | 2 +- RNTester/RNTesterUnitTests/RCTURLUtilsTests.m | 13 +++++ React/Base/RCTUtils.h | 13 +++++ React/Base/RCTUtils.m | 50 +++++++++++++++---- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/Libraries/Network/RCTFileRequestHandler.m b/Libraries/Network/RCTFileRequestHandler.m index da0b97968b2cab..bc2e14171a3908 100644 --- a/Libraries/Network/RCTFileRequestHandler.m +++ b/Libraries/Network/RCTFileRequestHandler.m @@ -30,7 +30,7 @@ - (BOOL)canHandleRequest:(NSURLRequest *)request { return [request.URL.scheme caseInsensitiveCompare:@"file"] == NSOrderedSame - && !RCTIsLocalAssetURL(request.URL); + && !RCTIsBundleAssetURL(request.URL); } - (NSOperation *)sendRequest:(NSURLRequest *)request diff --git a/RNTester/RNTesterUnitTests/RCTURLUtilsTests.m b/RNTester/RNTesterUnitTests/RCTURLUtilsTests.m index 7ee5abe84ed1b5..93b2601c5cbf20 100644 --- a/RNTester/RNTesterUnitTests/RCTURLUtilsTests.m +++ b/RNTester/RNTesterUnitTests/RCTURLUtilsTests.m @@ -90,4 +90,17 @@ - (void)testNilURLAppendQueryParam XCTAssertNil(result); } +- (void)testIsLocalAssetsURLParam +{ + NSString *libraryAssetsPath = [RCTLibraryPath() stringByAppendingPathComponent:@"assets/foo.png"]; + NSURL *libraryAssetsURL = [NSURL fileURLWithPath:libraryAssetsPath]; + XCTAssertTrue(RCTIsLocalAssetURL(libraryAssetsURL)); + NSString *bundleAssetsPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"assets/foo.png"]; + NSURL *bundleAssetsURL = [NSURL fileURLWithPath:bundleAssetsPath]; + XCTAssertTrue(RCTIsLocalAssetURL(bundleAssetsURL)); + NSString *otherAssetsPath = @"/assets/foo.png"; + NSURL *otherAssetsURL = [NSURL fileURLWithPath:otherAssetsPath]; + XCTAssertFalse(RCTIsLocalAssetURL(otherAssetsURL)); +} + @end diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index 9406c656b9d2ee..dcb2604a2fe0e3 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -115,6 +115,19 @@ RCT_EXTERN NSData *__nullable RCTGzipData(NSData *__nullable data, float level); // (or nil, if the URL does not specify a path within the main bundle) RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL); +// Returns the Path of Library directory +RCT_EXTERN NSString *__nullable RCTLibraryPath(void); + +// Returns the relative path within the library for an absolute URL +// (or nil, if the URL does not specify a path within the Library directory) +RCT_EXTERN NSString *__nullable RCTLibraryPathForURL(NSURL *__nullable URL); + +// Determines if a given image URL refers to a image in bundle +RCT_EXTERN BOOL RCTIsBundleAssetURL(NSURL *__nullable imageURL); + +// Determines if a given image URL refers to a image in library +RCT_EXTERN BOOL RCTIsLibraryAssetURL(NSURL *__nullable imageURL); + // Determines if a given image URL refers to a local image RCT_EXTERN BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index 5642753ef02e38..e1610a6f40ee9c 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -596,36 +596,66 @@ BOOL RCTIsGzippedData(NSData *__nullable data) return output; } -NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL) +static NSString *RCTRelativePathForURL(NSString *basePath, NSURL *__nullable URL) { if (!URL.fileURL) { // Not a file path return nil; } NSString *path = [NSString stringWithUTF8String:[URL fileSystemRepresentation]]; - NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; - if (![path hasPrefix:bundlePath]) { + if (![path hasPrefix:basePath]) { // Not a bundle-relative file return nil; } - path = [path substringFromIndex:bundlePath.length]; + path = [path substringFromIndex:basePath.length]; if ([path hasPrefix:@"/"]) { path = [path substringFromIndex:1]; } return path; } -BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL) +NSString *__nullable RCTLibraryPath(void) { - NSString *name = RCTBundlePathForURL(imageURL); - if (!name) { - return NO; - } + static NSString *libraryPath = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject]; + }); + return libraryPath; +} - NSString *extension = [name pathExtension]; +NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL) +{ + return RCTRelativePathForURL([[NSBundle mainBundle] resourcePath], URL); + +} + +NSString *__nullable RCTLibraryPathForURL(NSURL *__nullable URL) +{ + return RCTRelativePathForURL(RCTLibraryPath(), URL); +} + +static BOOL RCTIsImageAssetsPath(NSString *path) +{ + NSString *extension = [path pathExtension]; return [extension isEqualToString:@"png"] || [extension isEqualToString:@"jpg"]; } +BOOL RCTIsBundleAssetURL(NSURL *__nullable imageURL) +{ + return RCTIsImageAssetsPath(RCTBundlePathForURL(imageURL)); +} + +BOOL RCTIsLibraryAssetURL(NSURL *__nullable imageURL) +{ + return RCTIsImageAssetsPath(RCTLibraryPathForURL(imageURL)); +} + +BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL) +{ + return RCTIsBundleAssetURL(imageURL) || RCTIsLibraryAssetURL(imageURL); +} + static NSString *bundleName(NSBundle *bundle) { NSString *name = bundle.infoDictionary[@"CFBundleName"];