diff --git a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h index 94c10de8c..a038dbdee 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h +++ b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h @@ -20,6 +20,12 @@ #import #import +#if WK_WEB_VIEW_ONLY +#define CDVWebViewNavigationType int +#else +#define CDVWebViewNavigationType UIWebViewNavigationType +#endif + typedef NS_ENUM(NSInteger, CDVIntentAndNavigationFilterValue) { CDVIntentAndNavigationFilterValueIntentAllowed, CDVIntentAndNavigationFilterValueNavigationAllowed, @@ -29,6 +35,6 @@ typedef NS_ENUM(NSInteger, CDVIntentAndNavigationFilterValue) { @interface CDVIntentAndNavigationFilter : CDVPlugin + (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url intentsWhitelist:(CDVWhitelist*)intentsWhitelist navigationsWhitelist:(CDVWhitelist*)navigationsWhitelist; -+ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue; -+ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType; ++ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(CDVWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue; ++ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(CDVWebViewNavigationType)navigationType; @end diff --git a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m index ccfe77e9b..b656cd9eb 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m +++ b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m @@ -75,10 +75,10 @@ + (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url intentsWhitelist:(CD { // a URL can only allow-intent OR allow-navigation, if both are specified, // only allow-navigation is allowed - + BOOL allowNavigationsPass = [navigationsWhitelist URLIsAllowed:url logFailure:NO]; BOOL allowIntentPass = [intentsWhitelist URLIsAllowed:url logFailure:NO]; - + if (allowNavigationsPass && allowIntentPass) { return CDVIntentAndNavigationFilterValueNavigationAllowed; } else if (allowNavigationsPass) { @@ -86,7 +86,7 @@ + (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url intentsWhitelist:(CD } else if (allowIntentPass) { return CDVIntentAndNavigationFilterValueIntentAllowed; } - + return CDVIntentAndNavigationFilterValueNoneAllowed; } @@ -95,22 +95,30 @@ - (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url return [[self class] filterUrl:url intentsWhitelist:self.allowIntentsWhitelist navigationsWhitelist:self.allowNavigationsWhitelist]; } -+ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType +#if WK_WEB_VIEW_ONLY +#define CDVWebViewNavigationTypeLinkClicked 0 +#define CDVWebViewNavigationTypeOther 5 +#else +#define CDVWebViewNavigationTypeLinkClicked UIWebViewNavigationTypeLinkClicked +#define CDVWebViewNavigationTypeOther UIWebViewNavigationTypeOther +#endif + ++ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(CDVWebViewNavigationType)navigationType { - return (UIWebViewNavigationTypeLinkClicked == navigationType || - (UIWebViewNavigationTypeOther == navigationType && + return (CDVWebViewNavigationTypeLinkClicked == navigationType || + (CDVWebViewNavigationTypeOther == navigationType && [[request.mainDocumentURL absoluteString] isEqualToString:[request.URL absoluteString]] ) ); } -+ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue ++ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(CDVWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue { NSString* allowIntents_whitelistRejectionFormatString = @"ERROR External navigation rejected - not set for url='%@'"; NSString* allowNavigations_whitelistRejectionFormatString = @"ERROR Internal navigation rejected - not set for url='%@'"; - + NSURL* url = [request URL]; - + switch (filterValue) { case CDVIntentAndNavigationFilterValueNavigationAllowed: return YES; @@ -120,21 +128,21 @@ + (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIW if ([[self class] shouldOpenURLRequest:request navigationType:navigationType]){ [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil]; } - + // consume the request (i.e. no error) if it wasn't handled above return NO; case CDVIntentAndNavigationFilterValueNoneAllowed: // allow-navigation attempt failed for sure NSLog(@"%@", [NSString stringWithFormat:allowNavigations_whitelistRejectionFormatString, [url absoluteString]]); // anchor tag link means it was an allow-intent attempt that failed as well - if (UIWebViewNavigationTypeLinkClicked == navigationType) { + if (CDVWebViewNavigationTypeLinkClicked == navigationType) { NSLog(@"%@", [NSString stringWithFormat:allowIntents_whitelistRejectionFormatString, [url absoluteString]]); } return NO; } } -- (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType +- (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(CDVWebViewNavigationType)navigationType { return [[self class] shouldOverrideLoadWithRequest:request navigationType:navigationType filterValue:[self filterUrl:request.URL]]; } diff --git a/CordovaLib/Classes/Private/Plugins/CDVLocalStorage/CDVLocalStorage.m b/CordovaLib/Classes/Private/Plugins/CDVLocalStorage/CDVLocalStorage.m index 21b5cd9f4..25c48536d 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVLocalStorage/CDVLocalStorage.m +++ b/CordovaLib/Classes/Private/Plugins/CDVLocalStorage/CDVLocalStorage.m @@ -23,13 +23,19 @@ Licensed to the Apache Software Foundation (ASF) under one @interface CDVLocalStorage () @property (nonatomic, readwrite, strong) NSMutableArray* backupInfo; // array of CDVBackupInfo objects +#if !WK_WEB_VIEW_ONLY @property (nonatomic, readwrite, weak) id webviewDelegate; +#endif @end @implementation CDVLocalStorage +#if WK_WEB_VIEW_ONLY +@synthesize backupInfo; +#else @synthesize backupInfo, webviewDelegate; +#endif - (void)pluginInitialize { diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.h b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.h index 7db8a4ea7..8118d5f04 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.h +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.h @@ -17,6 +17,8 @@ under the License. */ +#if !WK_WEB_VIEW_ONLY + #import #import @@ -39,3 +41,5 @@ - (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest; @end + +#endif diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m index 93fbb67cc..ddef8be13 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m @@ -76,6 +76,8 @@ Licensed to the Apache Software Foundation (ASF) under one // TODO: Record order when page is re-navigated before the first navigation finishes. // +#if !WK_WEB_VIEW_ONLY + #import "CDVUIWebViewDelegate.h" // #define VerboseLog NSLog @@ -256,7 +258,7 @@ - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)re NSLog(@"%@", description); _loadCount = 0; _state = STATE_WAITING_FOR_LOAD_START; - + NSDictionary* errorDictionary = @{NSLocalizedDescriptionKey : description}; NSError* error = [[NSError alloc] initWithDomain:@"CDVUIWebViewDelegate" code:1 userInfo:errorDictionary]; [self webView:webView didFailLoadWithError:error]; @@ -402,3 +404,5 @@ - (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error } @end + +#endif diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.h b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.h index f4070092c..9b4bf187a 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.h +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.h @@ -22,6 +22,8 @@ @interface CDVUIWebViewEngine : CDVPlugin +#if !WK_WEB_VIEW_ONLY @property (nonatomic, strong, readonly) id uiWebViewDelegate; +#endif @end diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m index bbd343c15..e5767b5be 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m @@ -17,6 +17,8 @@ Licensed to the Apache Software Foundation (ASF) under one under the License. */ +#if !WK_WEB_VIEW_ONLY + #import "CDVUIWebViewEngine.h" #import "CDVUIWebViewDelegate.h" #import "CDVUIWebViewNavigationDelegate.h" @@ -200,3 +202,5 @@ - (UIView*)webView } @end + +#endif diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.h b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.h index 9138deba8..9b9b31f1f 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.h +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.h @@ -17,6 +17,8 @@ under the License. */ +#if !WK_WEB_VIEW_ONLY + #import #import "CDVUIWebViewEngine.h" @@ -27,3 +29,5 @@ - (instancetype)initWithEnginePlugin:(CDVPlugin*)enginePlugin; @end + +#endif diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.m b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.m index bc56fdde0..a918e2d7b 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.m +++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewNavigationDelegate.m @@ -17,6 +17,8 @@ Licensed to the Apache Software Foundation (ASF) under one under the License. */ +#if !WK_WEB_VIEW_ONLY + #import "CDVUIWebViewNavigationDelegate.h" #import #import @@ -94,7 +96,7 @@ - (BOOL)defaultResourcePolicyForURL:(NSURL*)url if ([url isFileURL]) { return YES; } - + return NO; } @@ -120,7 +122,7 @@ - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest* */ BOOL anyPluginsResponded = NO; BOOL shouldAllowRequest = NO; - + for (NSString* pluginName in vc.pluginObjects) { CDVPlugin* plugin = [vc.pluginObjects objectForKey:pluginName]; SEL selector = NSSelectorFromString(@"shouldOverrideLoadWithRequest:navigationType:"); @@ -132,7 +134,7 @@ - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest* } } } - + if (anyPluginsResponded) { return shouldAllowRequest; } @@ -146,8 +148,10 @@ - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest* } else { [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; } - + return NO; } @end + +#endif diff --git a/CordovaLib/Classes/Public/CDVUserAgentUtil.m b/CordovaLib/Classes/Public/CDVUserAgentUtil.m index 6eb591204..c5e9e2bcd 100644 --- a/CordovaLib/Classes/Public/CDVUserAgentUtil.m +++ b/CordovaLib/Classes/Public/CDVUserAgentUtil.m @@ -32,6 +32,40 @@ Licensed to the Apache Software Foundation (ASF) under one static NSInteger gCurrentLockToken = 0; static NSMutableArray* gPendingSetUserAgentBlocks = nil; +#if WK_WEB_VIEW_ONLY +#import + +@interface WKWebView(SynchronousEvaluateJavaScript) +- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script; +@end + +@implementation WKWebView(SynchronousEvaluateJavaScript) + +- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script +{ + __block NSString *resultString = nil; + __block BOOL finished = NO; + + [self evaluateJavaScript:script completionHandler:^(id result, NSError *error) { + if (error == nil) { + if (result != nil) { + resultString = [NSString stringWithFormat:@"%@", result]; + } + } else { + NSLog(@"evaluateJavaScript error : %@", error.localizedDescription); + } + finished = YES; + }]; + + while (!finished) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + } + + return resultString; +} +@end +#endif + @implementation CDVUserAgentUtil + (NSString*)originalUserAgent @@ -54,7 +88,11 @@ + (NSString*)originalUserAgent BOOL cachedValueIsOld = ![systemAndLocale isEqualToString:cordovaUserAgentVersion]; if ((gOriginalUserAgent == nil) || cachedValueIsOld) { + #if WK_WEB_VIEW_ONLY + WKWebView* sampleWebView = [[WKWebView alloc] initWithFrame:CGRectZero]; + #else UIWebView* sampleWebView = [[UIWebView alloc] initWithFrame:CGRectZero]; +#endif gOriginalUserAgent = [sampleWebView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]; [userDefaults setObject:gOriginalUserAgent forKey:kCdvUserAgentKey]; diff --git a/CordovaLib/Classes/Public/CDVViewController.m b/CordovaLib/Classes/Public/CDVViewController.m index 616d9ff3b..75e74add0 100644 --- a/CordovaLib/Classes/Public/CDVViewController.m +++ b/CordovaLib/Classes/Public/CDVViewController.m @@ -20,7 +20,6 @@ Licensed to the Apache Software Foundation (ASF) under one #import #import "CDV.h" #import "CDVPlugin+Private.h" -#import "CDVUIWebViewDelegate.h" #import "CDVConfigParser.h" #import "CDVUserAgentUtil.h" #import @@ -343,9 +342,9 @@ - (void)viewDidLoad } } }]; - + // ///////////////// - + NSString* bgColorString = [self.settings cordovaSettingForKey:@"BackgroundColor"]; UIColor* bgColor = [self colorFromColorString:bgColorString]; [self.webView setBackgroundColor:bgColor]; @@ -405,16 +404,16 @@ - (UIColor*)colorFromColorString:(NSString*)colorString if (!colorString) { return nil; } - + // Validate format NSError* error = NULL; NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"^(#[0-9A-F]{3}|(0x|#)([0-9A-F]{2})?[0-9A-F]{6})$" options:NSRegularExpressionCaseInsensitive error:&error]; NSUInteger countMatches = [regex numberOfMatchesInString:colorString options:0 range:NSMakeRange(0, [colorString length])]; - + if (!countMatches) { return nil; } - + // #FAB to #FFAABB if ([colorString hasPrefix:@"#"] && [colorString length] == 4) { NSString* r = [colorString substringWithRange:NSMakeRange(1, 1)]; @@ -422,22 +421,22 @@ - (UIColor*)colorFromColorString:(NSString*)colorString NSString* b = [colorString substringWithRange:NSMakeRange(3, 1)]; colorString = [NSString stringWithFormat:@"#%@%@%@%@%@%@", r, r, g, g, b, b]; } - + // #RRGGBB to 0xRRGGBB colorString = [colorString stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]; - + // 0xRRGGBB to 0xAARRGGBB if ([colorString hasPrefix:@"0x"] && [colorString length] == 8) { colorString = [@"0xFF" stringByAppendingString:[colorString substringFromIndex:2]]; } - + // 0xAARRGGBB to int unsigned colorValue = 0; NSScanner *scanner = [NSScanner scannerWithString:colorString]; if (![scanner scanHexInt:&colorValue]) { return nil; } - + // int to UIColor return [UIColor colorWithRed:((float)((colorValue & 0x00FF0000) >> 16))/255.0 green:((float)((colorValue & 0x0000FF00) >> 8))/255.0 @@ -480,9 +479,9 @@ - (BOOL)shouldAutorotate } // CB-12098 -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000 -- (NSUInteger)supportedInterfaceOrientations -#else +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000 +- (NSUInteger)supportedInterfaceOrientations +#else - (UIInterfaceOrientationMask)supportedInterfaceOrientations #endif { @@ -757,7 +756,7 @@ - (void)onAppWillEnterForeground:(NSNotification*)notification [self checkAndReinitViewUrl]; // NSLog(@"%@",@"applicationWillEnterForeground"); [self.commandDelegate evalJs:@"cordova.fireDocumentEvent('resume');"]; - + if (!IsAtLeastiOSVersion(@"11.0")) { /** Clipboard fix **/ UIPasteboard* pasteboard = [UIPasteboard generalPasteboard]; diff --git a/CordovaLib/Cordova/Cordova.h b/CordovaLib/Cordova/Cordova.h index 1d69468aa..8f3107709 100644 --- a/CordovaLib/Cordova/Cordova.h +++ b/CordovaLib/Cordova/Cordova.h @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -44,7 +44,6 @@ FOUNDATION_EXPORT const unsigned char CordovaVersionString[]; #import #import #import -#import #import #import #import diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index 682c4c55a..cb6716388 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -643,6 +643,7 @@ GCC_PREFIX_HEADER = CordovaLib_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "WK_WEB_VIEW_ONLY=$(WK_WEB_VIEW_ONLY)", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -659,6 +660,7 @@ PRODUCT_NAME = Cordova; SDKROOT = iphoneos; SKIP_INSTALL = YES; + WK_WEB_VIEW_ONLY = 0; }; name = Debug; }; @@ -703,6 +705,10 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = CordovaLib_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + "WK_WEB_VIEW_ONLY=$(WK_WEB_VIEW_ONLY)", + "$(inherited)", + ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -717,6 +723,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; VALIDATE_PRODUCT = YES; + WK_WEB_VIEW_ONLY = 0; }; name = Release; }; diff --git a/bin/lib/create.js b/bin/lib/create.js index ddf6cbfe5..07ea066e1 100755 --- a/bin/lib/create.js +++ b/bin/lib/create.js @@ -23,6 +23,7 @@ var shell = require('shelljs'); var Q = require('q'); var path = require('path'); var fs = require('fs'); +var xcode = require('xcode'); var xmlescape = require('xml-escape'); var ROOT = path.join(__dirname, '..', '..'); var events = require('cordova-common').events; @@ -32,7 +33,7 @@ function updateSubprojectHelp () { console.log('Usage: CordovaVersion/bin/update_cordova_project path/to/your/app.xcodeproj [path/to/CordovaLib.xcodeproj]'); } -function copyJsAndCordovaLib (projectPath, projectName, use_shared) { +function copyJsAndCordovaLib (projectPath, projectName, use_shared, config) { shell.cp('-f', path.join(ROOT, 'CordovaLib', 'cordova.js'), path.join(projectPath, 'www')); shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www')); shell.cp('-f', path.join(ROOT, 'CordovaLib', 'cordova.js'), path.join(projectPath, 'platform_www')); @@ -47,7 +48,7 @@ function copyJsAndCordovaLib (projectPath, projectName, use_shared) { } if (use_shared) { - update_cordova_subproject([path.join(projectPath, projectName + '.xcodeproj', 'project.pbxproj')]); + update_cordova_subproject([path.join(projectPath, projectName + '.xcodeproj', 'project.pbxproj'), config]); // Symlink not used in project file, but is currently required for plugman because // it reads the VERSION file from it (instead of using the cordova/version script // like it should). @@ -61,7 +62,7 @@ function copyJsAndCordovaLib (projectPath, projectName, use_shared) { shell.cp('-f', path.join(ROOT, 'CordovaLib', 'cordova.js'), path.join(projectPath, 'CordovaLib')); shell.cp('-f', path.join(ROOT, 'CordovaLib', 'CordovaLib_Prefix.pch'), path.join(projectPath, 'CordovaLib')); shell.cp('-f', path.join(ROOT, 'CordovaLib', 'CordovaLib.xcodeproj', 'project.pbxproj'), path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj')); - update_cordova_subproject([path.join(r + '.xcodeproj', 'project.pbxproj'), path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj', 'project.pbxproj')]); + update_cordova_subproject([path.join(r + '.xcodeproj', 'project.pbxproj'), path.join(projectPath, 'CordovaLib', 'CordovaLib.xcodeproj', 'project.pbxproj'), config]); } }); } @@ -197,7 +198,7 @@ function relpath (_path, start) { * - : Path to a project template (override) * */ -exports.createProject = function (project_path, package_name, project_name, opts) { +exports.createProject = function (project_path, package_name, project_name, opts, config) { package_name = package_name || 'my.cordova.project'; project_name = project_name || 'CordovaExample'; var use_shared = !!opts.link; @@ -233,7 +234,7 @@ exports.createProject = function (project_path, package_name, project_name, opts shell.cp('-rf', path.join(project_template_dir, '*.xcconfig'), project_path); // CordovaLib stuff - copyJsAndCordovaLib(project_path, project_name, use_shared); + copyJsAndCordovaLib(project_path, project_name, use_shared, config); copyScripts(project_path, project_name); events.emit('log', generateDoneMessage('create', use_shared)); @@ -264,17 +265,20 @@ function generateDoneMessage (type, link) { } function update_cordova_subproject (argv) { - if (argv.length < 1 || argv.length > 2) { + if (argv.length < 1 || argv.length > 3) { updateSubprojectHelp(); throw new Error('Usage error for update_cordova_subproject'); } var projectPath = AbsProjectPath(argv[0]); var cordovaLibXcodePath; - if (argv.length < 2) { + var projectConfig; + if (argv.length < 3) { cordovaLibXcodePath = path.join(ROOT, 'CordovaLib', 'CordovaLib.xcodeproj'); + projectConfig = argv[1]; } else { cordovaLibXcodePath = AbsProjectPath(argv[1]); + projectConfig = argv[2]; } var parentProjectPath = AbsParentPath(projectPath); @@ -301,6 +305,15 @@ function update_cordova_subproject (argv) { if (!found) { throw new Error('Entry not found in project file for sub-project: ' + subprojectPath); } + + var wkWebViewOnly = projectConfig.getPreference('WKWebViewOnly') === 'true'; + if (wkWebViewOnly) { + var pbxPath = path.join(cordovaLibXcodePath, 'project.pbxproj'); + var xcodeproj = xcode.project(pbxPath); + xcodeproj.parseSync(); + xcodeproj.updateBuildProperty('WK_WEB_VIEW_ONLY', '1'); + fs.writeFileSync(pbxPath, xcodeproj.writeSync()); + } } exports.updateSubprojectHelp = updateSubprojectHelp; diff --git a/bin/templates/project/__TEMP__.xcodeproj/project.pbxproj b/bin/templates/project/__TEMP__.xcodeproj/project.pbxproj index 0e6bc3bc3..58bee5dd4 100755 --- a/bin/templates/project/__TEMP__.xcodeproj/project.pbxproj +++ b/bin/templates/project/__TEMP__.xcodeproj/project.pbxproj @@ -389,6 +389,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SKIP_INSTALL = NO; + WK_WEB_VIEW_ONLY = 0; }; name = Debug; }; @@ -428,6 +429,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; SDKROOT = iphoneos; SKIP_INSTALL = NO; + WK_WEB_VIEW_ONLY = 0; }; name = Release; }; diff --git a/bin/templates/scripts/cordova/Api.js b/bin/templates/scripts/cordova/Api.js index 73c1dbcdf..4f85f3241 100644 --- a/bin/templates/scripts/cordova/Api.js +++ b/bin/templates/scripts/cordova/Api.js @@ -103,7 +103,7 @@ function Api (platform, platformRootDir, events) { * Creates platform in a specified directory. * * @param {String} destination Destination directory, where install platform to - * @param {ConfigParser} [config] ConfgiParser instance, used to retrieve + * @param {ConfigParser} [config] ConfigParser instance, used to retrieve * project creation options, such as package id and project name. * @param {Object} [options] An options object. The most common options are: * @param {String} [options.customTemplate] A path to custom template, that @@ -127,7 +127,7 @@ Api.createPlatform = function (destination, config, options, events) { var result; try { result = require('../../../lib/create') - .createProject(destination, config.getAttribute('ios-CFBundleIdentifier') || config.packageName(), name, options) + .createProject(destination, config.getAttribute('ios-CFBundleIdentifier') || config.packageName(), name, options, config) .then(function () { // after platform is created we return Api instance based on new Api.js location // This is required to correctly resolve paths in the future api calls diff --git a/bin/templates/scripts/cordova/build-debug.xcconfig b/bin/templates/scripts/cordova/build-debug.xcconfig index 3f4767d22..7e7985bb5 100644 --- a/bin/templates/scripts/cordova/build-debug.xcconfig +++ b/bin/templates/scripts/cordova/build-debug.xcconfig @@ -23,7 +23,7 @@ #include "build.xcconfig" -GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 #include "build-extras.xcconfig" diff --git a/bin/templates/scripts/cordova/build.xcconfig b/bin/templates/scripts/cordova/build.xcconfig index cc78c73e5..3c8b9307d 100644 --- a/bin/templates/scripts/cordova/build.xcconfig +++ b/bin/templates/scripts/cordova/build.xcconfig @@ -36,8 +36,10 @@ ENABLE_BITCODE = NO // (CB-9719) Set CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES to YES in build.xcconfig CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES -// (CB-10072) +// (CB-10072) SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h // (CB-11854) CODE_SIGN_ENTITLEMENTS = $(PROJECT_DIR)/$(PROJECT_NAME)/Entitlements-$(CONFIGURATION).plist + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) WK_WEB_VIEW_ONLY=$(WK_WEB_VIEW_ONLY) diff --git a/bin/templates/scripts/cordova/lib/prepare.js b/bin/templates/scripts/cordova/lib/prepare.js index a15380ed6..708e214cc 100644 --- a/bin/templates/scripts/cordova/lib/prepare.js +++ b/bin/templates/scripts/cordova/lib/prepare.js @@ -34,6 +34,7 @@ var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger; var PluginInfoProvider = require('cordova-common').PluginInfoProvider; var FileUpdater = require('cordova-common').FileUpdater; var projectFile = require('./projectFile'); +var xcode = require('xcode'); // launch storyboard and related constants var LAUNCHIMAGE_BUILD_SETTING = 'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME'; @@ -280,6 +281,7 @@ function handleBuildSettings (platformConfig, locations, infoPlist) { var deploymentTarget = platformConfig.getPreference('deployment-target', 'ios'); var needUpdatedBuildSettingsForLaunchStoryboard = checkIfBuildSettingsNeedUpdatedForLaunchStoryboard(platformConfig, infoPlist); var swiftVersion = platformConfig.getPreference('SwiftVersion', 'ios'); + var wkWebViewOnly = platformConfig.getPreference('WKWebViewOnly'); var project; @@ -293,7 +295,7 @@ function handleBuildSettings (platformConfig, locations, infoPlist) { // no build settings provided and we don't need to update build settings for launch storyboards, // then we don't need to parse and update .pbxproj file - if (origPkg === pkg && !targetDevice && !deploymentTarget && !needUpdatedBuildSettingsForLaunchStoryboard && !swiftVersion) { + if (origPkg === pkg && !targetDevice && !deploymentTarget && !needUpdatedBuildSettingsForLaunchStoryboard && !swiftVersion && !wkWebViewOnly) { return Q(); } @@ -316,6 +318,22 @@ function handleBuildSettings (platformConfig, locations, infoPlist) { events.emit('verbose', 'Set SwiftVersion to "' + swiftVersion + '".'); project.xcode.updateBuildProperty('SWIFT_VERSION', swiftVersion); } + if (wkWebViewOnly) { + var wkwebviewValue = '1'; + if (wkWebViewOnly === 'true') { + events.emit('verbose', 'Set WK_WEB_VIEW_ONLY.'); + } else { + wkwebviewValue = '0'; + events.emit('verbose', 'Unset WK_WEB_VIEW_ONLY.'); + } + project.xcode.updateBuildProperty('WK_WEB_VIEW_ONLY', wkwebviewValue); + var cordovaLibXcodePath = path.join(locations.root, 'CordovaLib', 'CordovaLib.xcodeproj'); + var pbxPath = path.join(cordovaLibXcodePath, 'project.pbxproj'); + var xcodeproj = xcode.project(pbxPath); + xcodeproj.parseSync(); + xcodeproj.updateBuildProperty('WK_WEB_VIEW_ONLY', wkwebviewValue); + fs.writeFileSync(pbxPath, xcodeproj.writeSync()); + } updateBuildSettingsForLaunchStoryboard(project.xcode, platformConfig, infoPlist);