Dynamically load WebKit

Summary:
@public

We can't dynamically link `WebKit` because doing so will impact cold start of all our Apps.

This diff includes a few changes:
 1. Weakly link the `WebKit` framework in the `ReactInternal` library, so that the compiler doesn't die when it encounters a WebKit symbol.
 2. Undo dynamic linking of WebKit in Catalyst.
 3. Undo dynamic linking of WebKit in AdsManager
 4. Before the first `WKWebView` is instantiated, dynamically load the `WebKit` framework.

The end result of these changes is that WebKit will be loaded only when it's going to be used.

Reviewed By: mmmulani

Differential Revision: D6564328

fbshipit-source-id: a45a44e774d0c61c1fb578a6fa3d16bb08f68ac9
This commit is contained in:
Ramanpreet Nara 2018-08-16 13:34:33 -07:00 committed by Facebook Github Bot
parent b18fddadfe
commit 28b058c341
3 changed files with 36 additions and 2 deletions

View File

@ -69,6 +69,9 @@ typedef NSURL RCTFileURL;
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
#if !TARGET_OS_TV
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
#endif
#if TARGET_OS_IPHONE
+ (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
#endif

View File

@ -5240,7 +5240,11 @@
"RCT_METRO_PORT=${RCT_METRO_PORT}",
);
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
OTHER_LDFLAGS = "-ObjC";
OTHER_LDFLAGS = (
"-ObjC",
"-weak_framework",
WebKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/React;
RUN_CLANG_STATIC_ANALYZER = YES;
@ -5258,7 +5262,11 @@
"RCT_METRO_PORT=${RCT_METRO_PORT}",
);
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
OTHER_LDFLAGS = "-ObjC";
OTHER_LDFLAGS = (
"-ObjC",
"-weak_framework",
WebKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/React;
RUN_CLANG_STATIC_ANALYZER = NO;

View File

@ -23,6 +23,25 @@ static NSString *const MessageHanderName = @"ReactNative";
}
/**
* See https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DisplayWebContent/Tasks/WebKitAvail.html.
*/
+ (BOOL)dynamicallyLoadWebKitIfAvailable
{
static BOOL _webkitAvailable=NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *webKitBundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/WebKit.framework"];
if (webKitBundle) {
_webkitAvailable = [webKitBundle load];
}
});
return _webkitAvailable;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
@ -38,6 +57,10 @@ static NSString *const MessageHanderName = @"ReactNative";
- (void)didMoveToWindow
{
if (self.window != nil) {
if (![[self class] dynamicallyLoadWebKitIfAvailable]) {
return;
};
WKWebViewConfiguration *wkWebViewConfig = [WKWebViewConfiguration new];
wkWebViewConfig.userContentController = [WKUserContentController new];
[wkWebViewConfig.userContentController addScriptMessageHandler: self name: MessageHanderName];