mirror of
https://github.com/status-im/react-native.git
synced 2025-02-25 15:45:32 +00:00
Added support for URLs pointing to files inside application home
This commit is contained in:
parent
d1b14ef062
commit
90dd7a13f0
@ -15,6 +15,7 @@
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@interface RCTConvert_NSURLTests : XCTestCase
|
||||
|
||||
@ -42,7 +43,7 @@ TEST_PATH(name, _input, [[[NSBundle mainBundle] bundlePath] stringByAppendingPat
|
||||
TEST_URL(basic, @"http://example.com", @"http://example.com")
|
||||
TEST_URL(null, (id)kCFNull, nil)
|
||||
|
||||
// Local files
|
||||
// Resource files
|
||||
TEST_PATH(fileURL, @"file:///blah/hello.jsbundle", @"/blah/hello.jsbundle")
|
||||
TEST_BUNDLE_PATH(filePath, @"blah/hello.jsbundle", @"blah/hello.jsbundle")
|
||||
TEST_BUNDLE_PATH(filePathWithSpaces, @"blah blah/hello.jsbundle", @"blah blah/hello.jsbundle")
|
||||
@ -50,6 +51,9 @@ TEST_BUNDLE_PATH(filePathWithEncodedSpaces, @"blah%20blah/hello.jsbundle", @"bla
|
||||
TEST_BUNDLE_PATH(imageAt2XPath, @"images/foo@2x.jpg", @"images/foo@2x.jpg")
|
||||
TEST_BUNDLE_PATH(imageFile, @"foo.jpg", @"foo.jpg")
|
||||
|
||||
// User documents
|
||||
TEST_PATH(documentsFolder, @"~/Documents", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject])
|
||||
|
||||
// Remote files
|
||||
TEST_URL(fullURL, @"http://example.com/blah/hello.jsbundle", @"http://example.com/blah/hello.jsbundle")
|
||||
TEST_URL(urlWithSpaces, @"http://example.com/blah blah/foo", @"http://example.com/blah%20blah/foo")
|
||||
@ -57,4 +61,12 @@ TEST_URL(urlWithEncodedSpaces, @"http://example.com/blah%20blah/foo", @"http://e
|
||||
TEST_URL(imageURL, @"http://example.com/foo@2x.jpg", @"http://example.com/foo@2x.jpg")
|
||||
TEST_URL(imageURLWithSpaces, @"http://example.com/blah foo@2x.jpg", @"http://example.com/blah%20foo@2x.jpg")
|
||||
|
||||
// Data URLs
|
||||
- (void)testDataURL
|
||||
{
|
||||
NSURL *expectedURL = RCTDataURL(@"text/plain", [@"abcde" dataUsingEncoding:NSUTF8StringEncoding]);
|
||||
NSURL *testURL = [NSURL URLWithString:@"data:text/plain;base64,YWJjZGU="];
|
||||
XCTAssertEqualObjects([testURL absoluteString], [expectedURL absoluteString]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -107,7 +107,11 @@ RCT_CONVERTER(NSString *, NSString, description)
|
||||
|
||||
// Assume that it's a local path
|
||||
path = [path stringByRemovingPercentEncoding];
|
||||
if (![path isAbsolutePath]) {
|
||||
if ([path hasPrefix:@"~"]) {
|
||||
// Path is inside user directory
|
||||
path = [path stringByExpandingTildeInPath];
|
||||
} else if (![path isAbsolutePath]) {
|
||||
// Assume it's a resource path
|
||||
path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:path];
|
||||
}
|
||||
return [NSURL fileURLWithPath:path];
|
||||
@ -652,43 +656,54 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (RCT_DEBUG && ![json isKindOfClass:[NSString class]] && ![json isKindOfClass:[NSDictionary class]]) {
|
||||
RCTLogConvertError(json, "an image");
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIImage *image;
|
||||
NSString *path;
|
||||
CGFloat scale = 0.0;
|
||||
if ([json isKindOfClass:[NSString class]]) {
|
||||
if ([json length] == 0) {
|
||||
return nil;
|
||||
}
|
||||
path = json;
|
||||
} else {
|
||||
} else if ([json isKindOfClass:[NSDictionary class]]) {
|
||||
path = [self NSString:json[@"uri"]];
|
||||
scale = [self CGFloat:json[@"scale"]];
|
||||
} else {
|
||||
RCTLogConvertError(json, "an image");
|
||||
}
|
||||
|
||||
if ([path hasPrefix:@"data:"]) {
|
||||
NSURL *url = [NSURL URLWithString:path];
|
||||
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
||||
image = [UIImage imageWithData:imageData];
|
||||
} else if ([path isAbsolutePath] || [path hasPrefix:@"~"]) {
|
||||
image = [UIImage imageWithContentsOfFile:path.stringByExpandingTildeInPath];
|
||||
} else {
|
||||
image = [UIImage imageNamed:path];
|
||||
if (!image) {
|
||||
image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:nil]];
|
||||
NSURL *URL = [self NSURL:path];
|
||||
NSString *scheme = [URL.scheme lowercaseString];
|
||||
if ([scheme isEqualToString:@"file"]) {
|
||||
|
||||
if ([NSThread currentThread] == [NSThread mainThread]) {
|
||||
// Image may reside inside a .car file, in which case we have no choice
|
||||
// but to use +[UIImage imageNamed] - but this method isn't thread safe
|
||||
image = [UIImage imageNamed:path];
|
||||
}
|
||||
|
||||
if (!image) {
|
||||
// Attempt to load from the file system
|
||||
if ([path pathExtension].length == 0) {
|
||||
path = [path stringByAppendingPathExtension:@"png"];
|
||||
}
|
||||
image = [UIImage imageWithContentsOfFile:path];
|
||||
}
|
||||
|
||||
// We won't warn about nil images because there are legitimate cases
|
||||
// where we find out if a string is an image by using this method, but
|
||||
// we do enforce thread-safe API usage with the following check
|
||||
if (RCT_DEBUG && !image && [UIImage imageNamed:path]) {
|
||||
RCTAssertMainThread();
|
||||
}
|
||||
|
||||
} else if ([scheme isEqualToString:@"data"]) {
|
||||
image = [UIImage imageWithData:[NSData dataWithContentsOfURL:URL]];
|
||||
} else {
|
||||
RCTLogConvertError(json, "an image. Only local files or data URIs are supported");
|
||||
}
|
||||
|
||||
|
||||
if (scale > 0) {
|
||||
image = [UIImage imageWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
image = [UIImage imageWithCGImage:image.CGImage
|
||||
scale:scale
|
||||
orientation:image.imageOrientation];
|
||||
}
|
||||
|
||||
// NOTE: we don't warn about nil images because there are legitimate
|
||||
// case where we find out if a string is an image by using this method
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
||||
// Creates a standardized error object
|
||||
RCT_EXTERN NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData);
|
||||
RCT_EXTERN NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData);
|
||||
RCT_EXTERN NSDictionary *RCTJSErrorFromNSError(NSError *error);
|
||||
|
||||
// Returns YES if React is running in a test environment
|
||||
RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
|
||||
@ -58,7 +59,8 @@ RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image);
|
||||
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
|
||||
|
||||
// Convert nil values to NSNull, and vice-versa
|
||||
RCT_EXTERN id RCTNullIfNil(id value);
|
||||
RCT_EXTERN id RCTNilIfNull(id value);
|
||||
RCT_EXTERN id RCTNullIfNil(id value);
|
||||
|
||||
RCT_EXTERN NSDictionary *RCTJSErrorFromNSError(NSError *error);
|
||||
// Convert data to a Base64-encoded data URL
|
||||
RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
|
||||
|
@ -238,6 +238,27 @@ NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary
|
||||
return error;
|
||||
}
|
||||
|
||||
// TODO: Can we just replace RCTMakeError with this function instead?
|
||||
NSDictionary *RCTJSErrorFromNSError(NSError *error)
|
||||
{
|
||||
NSString *errorMessage;
|
||||
NSArray *stackTrace = [NSThread callStackSymbols];
|
||||
NSMutableDictionary *errorInfo =
|
||||
[NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"];
|
||||
|
||||
if (error) {
|
||||
errorMessage = error.localizedDescription ?: @"Unknown error from a native module";
|
||||
errorInfo[@"domain"] = error.domain ?: RCTErrorDomain;
|
||||
errorInfo[@"code"] = @(error.code);
|
||||
} else {
|
||||
errorMessage = @"Unknown error from a native module";
|
||||
errorInfo[@"domain"] = RCTErrorDomain;
|
||||
errorInfo[@"code"] = @-1;
|
||||
}
|
||||
|
||||
return RCTMakeError(errorMessage, nil, errorInfo);
|
||||
}
|
||||
|
||||
BOOL RCTRunningInTestEnvironment(void)
|
||||
{
|
||||
static BOOL isTestEnvironment = NO;
|
||||
@ -277,23 +298,10 @@ id RCTNilIfNull(id value)
|
||||
return value == (id)kCFNull ? nil : value;
|
||||
}
|
||||
|
||||
// TODO: Can we just replace RCTMakeError with this function instead?
|
||||
NSDictionary *RCTJSErrorFromNSError(NSError *error)
|
||||
NSURL *RCTDataURL(NSString *mimeType, NSData *data)
|
||||
{
|
||||
NSString *errorMessage;
|
||||
NSArray *stackTrace = [NSThread callStackSymbols];
|
||||
NSMutableDictionary *errorInfo =
|
||||
[NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"];
|
||||
|
||||
if (error) {
|
||||
errorMessage = error.localizedDescription ?: @"Unknown error from a native module";
|
||||
errorInfo[@"domain"] = error.domain ?: RCTErrorDomain;
|
||||
errorInfo[@"code"] = @(error.code);
|
||||
} else {
|
||||
errorMessage = @"Unknown error from a native module";
|
||||
errorInfo[@"domain"] = RCTErrorDomain;
|
||||
errorInfo[@"code"] = @-1;
|
||||
}
|
||||
|
||||
return RCTMakeError(errorMessage, nil, errorInfo);
|
||||
return [NSURL URLWithString:
|
||||
[NSString stringWithFormat:@"data:%@;base64,%@", mimeType,
|
||||
[data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user