|
1 | 1 | #if defined(__has_include) |
2 | 2 | #if __has_include("CDVWKWebViewEngine.h") |
3 | 3 |
|
4 | | -#import <Cordova/NSDictionary+CordovaPreferences.h> |
5 | 4 | #import "CDVWKWebViewEngine.h" |
6 | | -#import "CodePush.h" |
| 5 | +#import "WebViewShared.h" |
7 | 6 |
|
8 | 7 | @implementation CDVWKWebViewEngine (CodePush) |
9 | 8 |
|
10 | | -NSString* const IdentifierCodePushPath = @"codepush/deploy/versions"; |
11 | 9 | NSString* lastLoadedURL = @""; |
12 | 10 |
|
13 | 11 | #pragma clang diagnostic push |
14 | 12 | #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" |
15 | 13 |
|
16 | 14 | - (id)loadRequest:(NSURLRequest *)request { |
17 | 15 | lastLoadedURL = request.URL.absoluteString; |
18 | | - NSURL *readAccessURL; |
19 | | - |
20 | | - NSURL* bundleURL = [[NSBundle mainBundle] bundleURL]; |
21 | | - if (![lastLoadedURL containsString:bundleURL.path] && ![lastLoadedURL containsString:IdentifierCodePushPath]) { |
22 | | - return [self loadPluginRequest:request]; |
23 | | - } |
24 | | - |
25 | | - if (request.URL.isFileURL) { |
26 | | - // All file URL requests should be handled with the setServerBasePath in case if it is Ionic app. |
27 | | - if ([CodePush hasIonicWebViewEngine: self]) { |
28 | | - NSString* specifiedServerPath = [CodePush getCurrentServerBasePath]; |
29 | | - if (![specifiedServerPath containsString:IdentifierCodePushPath] || [request.URL.path containsString:IdentifierCodePushPath]) { |
30 | | - [CodePush setServerBasePath:request.URL.path webView: self]; |
31 | | - } |
32 | | - |
33 | | - return nil; |
34 | | - } |
35 | | - |
36 | | - if ([request.URL.absoluteString containsString:IdentifierCodePushPath]) { |
37 | | - // If the app is attempting to load a CodePush update, then we can lock the WebView down to |
38 | | - // just the CodePush "versions" directory. This prevents non-CodePush assets from being accessible, |
39 | | - // while still allowing us to navigate to a future update, as well as to the binary if a rollback is needed. |
40 | | - NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0]; |
41 | | - readAccessURL = [NSURL fileURLWithPathComponents:@[libraryPath, @"NoCloud", @"codepush", @"deploy", @"versions"]]; |
42 | | - } else { |
43 | | - // In order to allow the WebView to be navigated from the app bundle to another location, we (for some |
44 | | - // entirely unknown reason) need to ensure that the "read access URL" is set to the parent of the bundle |
45 | | - // as opposed to the www folder, which is what the WKWebViewEngine would attempt to set it to by default. |
46 | | - // If we didn't set this, then the attempt to navigate from the bundle to a CodePush update would fail. |
47 | | - readAccessURL = [[[NSBundle mainBundle] bundleURL] URLByDeletingLastPathComponent]; |
48 | | - } |
49 | | - |
50 | | - return [(WKWebView*)self.engineWebView loadFileURL:request.URL allowingReadAccessToURL:readAccessURL]; |
51 | | - } else { |
52 | | - return [(WKWebView*)self.engineWebView loadRequest: request]; |
53 | | - } |
54 | | -} |
55 | | - |
56 | | -- (id)loadPluginRequest:(NSURLRequest *)request { |
57 | | - if (request.URL.fileURL) { |
58 | | - NSDictionary* settings = self.commandDelegate.settings; |
59 | | - NSString *bind = [settings cordovaSettingForKey:@"Hostname"]; |
60 | | - if(bind == nil){ |
61 | | - bind = @"localhost"; |
62 | | - } |
63 | | - NSString *scheme = [settings cordovaSettingForKey:@"iosScheme"]; |
64 | | - if(scheme == nil || [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"] || [scheme isEqualToString:@"file"]){ |
65 | | - scheme = @"ionic"; |
66 | | - } |
67 | | - NSString *CDV_LOCAL_SERVER = [NSString stringWithFormat:@"%@://%@", scheme, bind]; |
68 | | - |
69 | | - NSURL* startURL = [NSURL URLWithString:((CDVViewController *)self.viewController).startPage]; |
70 | | - NSString* startFilePath = [self.commandDelegate pathForResource:[startURL path]]; |
71 | | - NSURL *url = [[NSURL URLWithString:CDV_LOCAL_SERVER] URLByAppendingPathComponent:request.URL.path]; |
72 | | - if ([request.URL.path isEqualToString:startFilePath]) { |
73 | | - url = [NSURL URLWithString:CDV_LOCAL_SERVER]; |
74 | | - } |
75 | | - if(request.URL.query) { |
76 | | - url = [NSURL URLWithString:[@"?" stringByAppendingString:request.URL.query] relativeToURL:url]; |
77 | | - } |
78 | | - if(request.URL.fragment) { |
79 | | - url = [NSURL URLWithString:[@"#" stringByAppendingString:request.URL.fragment] relativeToURL:url]; |
80 | | - } |
81 | | - request = [NSURLRequest requestWithURL:url]; |
82 | | - } |
83 | | - return [(WKWebView*)self.engineWebView loadRequest:request]; |
| 16 | + WebViewShared* webViewShared = [WebViewShared getInstanceOrCreate:self.webViewEngine |
| 17 | + andCommandDelegate:self.commandDelegate |
| 18 | + andViewController:self.viewController]; |
| 19 | + return [webViewShared loadRequest:request]; |
84 | 20 | } |
85 | 21 |
|
86 | 22 | #pragma clang diagnostic pop |
87 | 23 |
|
88 | 24 | // Fix bug related to unable WKWebView recovery after reinit with loaded codepush update |
89 | 25 | - (void)webView:(WKWebView*)theWebView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error { |
90 | 26 | // NSURLErrorFailingURLStringErrorKey is URL which caused a load to fail, if it's null then webView was terminated for some reason |
91 | | - if ([[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey] == nil && [lastLoadedURL containsString:IdentifierCodePushPath]) { |
| 27 | + if ([[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey] == nil && [lastLoadedURL containsString:[WebViewShared getIdentifierCodePushPath]]) { |
92 | 28 | NSLog(@"Failed to load webpage with error: %@", [error localizedDescription]); |
93 | 29 | NSLog(@"Trying to reload request with url: %@", lastLoadedURL); |
94 | 30 | // Manually loading codepush start page via loadRequest method of this category |
|
0 commit comments