diff --git a/CordovaLib/Classes/Public/CDVViewController.m b/CordovaLib/Classes/Public/CDVViewController.m index 415728348..8277b1627 100644 --- a/CordovaLib/Classes/Public/CDVViewController.m +++ b/CordovaLib/Classes/Public/CDVViewController.m @@ -485,37 +485,61 @@ - (BOOL)supportsOrientation:(UIInterfaceOrientation)orientation return [self.supportedOrientations containsObject:@(orientation)]; } -- (UIView*)newCordovaViewWithFrame:(CGRect)bounds +/// Retrieves the view from a newwly initialized webViewEngine +/// @param bounds The bounds with which the webViewEngine will be initialized +- (nonnull UIView*)newCordovaViewWithFrame:(CGRect)bounds { - NSString* defaultWebViewEngineClass = [self.settings cordovaSettingForKey:@"CordovaDefaultWebViewEngine"]; - NSString* webViewEngineClass = [self.settings cordovaSettingForKey:@"CordovaWebViewEngine"]; + NSString* defaultWebViewEngineClassName = [self.settings cordovaSettingForKey:@"CordovaDefaultWebViewEngine"]; + NSString* webViewEngineClassName = [self.settings cordovaSettingForKey:@"CordovaWebViewEngine"]; - if (!defaultWebViewEngineClass) { - defaultWebViewEngineClass = @"CDVWebViewEngine"; + if (!defaultWebViewEngineClassName) { + defaultWebViewEngineClassName = @"CDVWebViewEngine"; } - if (!webViewEngineClass) { - webViewEngineClass = defaultWebViewEngineClass; + if (!webViewEngineClassName) { + webViewEngineClassName = defaultWebViewEngineClassName; } - // Find webViewEngine - if (NSClassFromString(webViewEngineClass)) { - self.webViewEngine = [[NSClassFromString(webViewEngineClass) alloc] initWithFrame:bounds]; - // if a webView engine returns nil (not supported by the current iOS version) or doesn't conform to the protocol, or can't load the request, we use WKWebView - if (!self.webViewEngine || ![self.webViewEngine conformsToProtocol:@protocol(CDVWebViewEngineProtocol)] || ![self.webViewEngine canLoadRequest:[NSURLRequest requestWithURL:self.appUrl]]) { - self.webViewEngine = [[NSClassFromString(defaultWebViewEngineClass) alloc] initWithFrame:bounds]; + // Determine if a provided custom web view engine is sufficient + id engine; + Class customWebViewEngineClass = NSClassFromString(webViewEngineClassName); + if (customWebViewEngineClass) { + id customWebViewEngine = [self initWebViewEngine:customWebViewEngineClass bounds:bounds]; + BOOL customConformsToProtocol = [customWebViewEngine conformsToProtocol:@protocol(CDVWebViewEngineProtocol)]; + BOOL customCanLoad = [customWebViewEngine canLoadRequest:[NSURLRequest requestWithURL:self.appUrl]]; + if (customConformsToProtocol && customCanLoad) { + engine = customWebViewEngine; } - } else { - WKWebViewConfiguration *config = [self respondsToSelector:@selector(configuration)] ? [self configuration] : nil; - self.webViewEngine = [[NSClassFromString(defaultWebViewEngineClass) alloc] initWithFrame:bounds configuration:config]; } - if ([self.webViewEngine isKindOfClass:[CDVPlugin class]]) { - [self registerPlugin:(CDVPlugin*)self.webViewEngine withClassName:webViewEngineClass]; + // Otherwise use the default web view engine + if (!engine) { + Class defaultWebViewEngineClass = NSClassFromString(defaultWebViewEngineClassName); + id defaultWebViewEngine = [self initWebViewEngine:defaultWebViewEngineClass bounds:bounds]; + NSAssert([defaultWebViewEngine conformsToProtocol:@protocol(CDVWebViewEngineProtocol)], + @"we expected the default web view engine to conform to the CDVWebViewEngineProtocol"); + engine = defaultWebViewEngine; + } + + if ([engine isKindOfClass:[CDVPlugin class]]) { + [self registerPlugin:(CDVPlugin*)engine withClassName:webViewEngineClassName]; } + self.webViewEngine = engine; return self.webViewEngine.engineWebView; } +/// Initialiizes the webViewEngine, with config, if supported and provided +/// @param engineClass A class that must conform to the `CDVWebViewEngineProtocol` +/// @param bounds with which the webview will be initialized +- (id _Nullable) initWebViewEngine:(nonnull Class)engineClass bounds:(CGRect)bounds { + if ([engineClass respondsToSelector:@selector(initWithFrame:configuration:)]) { + WKWebViewConfiguration *config = [self respondsToSelector:@selector(configuration)] ? [self configuration] : nil; + return [[engineClass alloc] initWithFrame:bounds configuration:config]; + } else { + return [[engineClass alloc] initWithFrame:bounds]; + } +} + - (void)createLaunchView { CGRect webViewBounds = self.view.bounds;