2015-04-19 19:55:46 +00:00
/ * *
* Copyright ( c ) 2015 - present , Facebook , Inc .
* All rights reserved .
*
* This source code is licensed under the BSD - style license found in the
* LICENSE file in the root directory of this source tree . An additional grant
* of patent rights can be found in the PATENTS file in the same directory .
* /
2015-04-02 14:33:21 +00:00
# import "RCTJavaScriptLoader.h"
# import "RCTBridge.h"
2015-04-25 21:52:18 +00:00
# import "RCTConvert.h"
2015-04-02 14:33:21 +00:00
# import "RCTSourceCode.h"
# import "RCTUtils.h"
@ implementation RCTJavaScriptLoader
{
2015-04-10 14:28:10 +00:00
__weak RCTBridge * _bridge ;
2015-04-02 14:33:21 +00:00
}
- ( instancetype ) initWithBridge : ( RCTBridge * ) bridge
{
2015-07-07 23:19:40 +00:00
RCTAssert ( bridge , @ "bridge parameter is required" ) ;
2015-06-15 14:53:45 +00:00
2015-04-11 22:08:00 +00:00
if ( ( self = [ super init ] ) ) {
2015-04-02 14:33:21 +00:00
_bridge = bridge ;
}
return self ;
}
2015-06-15 14:53:45 +00:00
RCT_NOT _IMPLEMENTED ( - init )
2015-05-04 17:35:49 +00:00
- ( void ) loadBundleAtURL : ( NSURL * ) scriptURL onComplete : ( void ( ^ ) ( NSError * , NSString * ) ) onComplete
2015-04-02 14:33:21 +00:00
{
2015-04-25 21:52:18 +00:00
// Sanitize the script URL
scriptURL = [ RCTConvert NSURL : scriptURL . absoluteString ] ;
if ( ! scriptURL ||
( [ scriptURL isFileURL ] && ! [ [ NSFileManager defaultManager ] fileExistsAtPath : scriptURL . path ] ) ) {
2015-04-11 22:08:00 +00:00
NSError * error = [ NSError errorWithDomain : @ "JavaScriptLoader" code : 1 userInfo : @ {
2015-04-25 21:52:18 +00:00
NSLocalizedDescriptionKey : scriptURL ? [ NSString stringWithFormat : @ "Script at '%@' could not be found." , scriptURL ] : @ "No script URL provided"
2015-04-11 22:08:00 +00:00
} ] ;
2015-05-04 17:35:49 +00:00
onComplete ( error , nil ) ;
2015-04-02 14:33:21 +00:00
return ;
2015-04-11 22:08:00 +00:00
}
2015-04-02 14:33:21 +00:00
NSURLSessionDataTask * task = [ [ NSURLSession sharedSession ] dataTaskWithURL : scriptURL completionHandler :
^ ( NSData * data , NSURLResponse * response , NSError * error ) {
2015-04-25 21:52:18 +00:00
// Handle general request errors
if ( error ) {
if ( [ [ error domain ] isEqualToString : NSURLErrorDomain ] ) {
NSString * desc = [ @ "Could not connect to development server. Ensure node server is running and available on the same network - run 'npm start' from react-native root\n\nURL: " stringByAppendingString : [ scriptURL absoluteString ] ] ;
NSDictionary * userInfo = @ {
NSLocalizedDescriptionKey : desc ,
NSLocalizedFailureReasonErrorKey : [ error localizedDescription ] ,
NSUnderlyingErrorKey : error ,
} ;
error = [ NSError errorWithDomain : @ "JSServer"
code : error . code
userInfo : userInfo ] ;
}
2015-05-04 17:35:49 +00:00
onComplete ( error , nil ) ;
2015-04-25 21:52:18 +00:00
return ;
}
2015-04-23 21:39:51 +00:00
2015-04-25 21:52:18 +00:00
// Parse response as text
NSStringEncoding encoding = NSUTF8StringEncoding ;
if ( response . textEncodingName ! = nil ) {
CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding ( ( CFStringRef ) response . textEncodingName ) ;
if ( cfEncoding ! = kCFStringEncodingInvalidId ) {
encoding = CFStringConvertEncodingToNSStringEncoding ( cfEncoding ) ;
}
}
NSString * rawText = [ [ NSString alloc ] initWithData : data encoding : encoding ] ;
// Handle HTTP errors
if ( [ response isKindOfClass : [ NSHTTPURLResponse class ] ] && [ ( NSHTTPURLResponse * ) response statusCode ] ! = 200 ) {
NSDictionary * userInfo ;
NSDictionary * errorDetails = RCTJSONParse ( rawText , nil ) ;
if ( [ errorDetails isKindOfClass : [ NSDictionary class ] ] &&
[ errorDetails [ @ "errors" ] isKindOfClass : [ NSArray class ] ] ) {
NSMutableArray * fakeStack = [ [ NSMutableArray alloc ] init ] ;
for ( NSDictionary * err in errorDetails [ @ "errors" ] ) {
[ fakeStack addObject : @ {
@ "methodName" : err [ @ "description" ] ? : @ "" ,
@ "file" : err [ @ "filename" ] ? : @ "" ,
@ "lineNumber" : err [ @ "lineNumber" ] ? : @ 0
} ] ;
}
userInfo = @ {
NSLocalizedDescriptionKey : errorDetails [ @ "message" ] ? : @ "No message provided" ,
@ "stack" : fakeStack ,
} ;
} else {
userInfo = @ { NSLocalizedDescriptionKey : rawText } ;
}
error = [ NSError errorWithDomain : @ "JSServer"
code : [ ( NSHTTPURLResponse * ) response statusCode ]
userInfo : userInfo ] ;
2015-05-04 17:35:49 +00:00
onComplete ( error , nil ) ;
2015-04-25 21:52:18 +00:00
return ;
}
2015-05-04 17:35:49 +00:00
onComplete ( nil , rawText ) ;
2015-04-25 21:52:18 +00:00
} ] ;
2015-04-02 14:33:21 +00:00
[ task resume ] ;
}
@ end