diff --git a/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.h b/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.h index 97800a68eb..41db2e25fc 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.h +++ b/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.h @@ -18,8 +18,9 @@ */ #import "WXComponent.h" +#import -@interface WXWebComponent : WXComponent +@interface WXWebComponent : WXComponent - (void)notifyWebview:(NSDictionary *) data; diff --git a/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.m index cd1007851a..1b37c28c49 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.m +++ b/ios/sdk/WeexSDK/Sources/Component/WXWebComponent.m @@ -26,7 +26,7 @@ #import -@interface WXWebView : UIWebView +@interface WXWebView : WKWebView @end @@ -84,17 +84,27 @@ - (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDict return self; } +- (WKWebViewConfiguration *)baseConfiguration { + WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; + NSString *scalesPageToFitScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"; + WKUserScript *userScript = [[WKUserScript alloc] initWithSource:scalesPageToFitScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES]; + WKUserContentController *userContentController = [[WKUserContentController alloc] init]; + [userContentController addUserScript:userScript]; + configuration.userContentController = userContentController; + configuration.allowsInlineMediaPlayback = YES; + + return configuration; +} + - (UIView *)loadView { - return [[WXWebView alloc] init]; + return [[WXWebView alloc] initWithFrame:self.view.frame configuration:[self baseConfiguration]]; } - (void)viewDidLoad { _webview = (WXWebView *)self.view; - _webview.delegate = self; - _webview.allowsInlineMediaPlayback = YES; - _webview.scalesPageToFit = YES; + _webview.navigationDelegate = self; [_webview setBackgroundColor:[UIColor clearColor]]; _webview.opaque = NO; _jsContext = [_webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; @@ -254,56 +264,61 @@ - (void)postMessage:(NSDictionary *)data { #pragma mark Webview Delegate -- (NSMutableDictionary *)baseInfo -{ +- (void)baseInfoWithCompletion:(void (^)(NSMutableDictionary *data))completion { NSMutableDictionary *info = [NSMutableDictionary new]; - [info setObject:self.webview.request.URL.absoluteString ?: @"" forKey:@"url"]; - [info setObject:[self.webview stringByEvaluatingJavaScriptFromString:@"document.title"] ?: @"" forKey:@"title"]; + [info setObject:self.webview.URL.absoluteString ?: @"" forKey:@"url"]; [info setObject:@(self.webview.canGoBack) forKey:@"canGoBack"]; [info setObject:@(self.webview.canGoForward) forKey:@"canGoForward"]; - return info; + [self.webview evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable result, NSError * _Nullable error) { + [info setObject:result ? result : @"" forKey:@"title"]; + if (completion) { + completion(result); + } + }]; } -- (void)webViewDidStartLoad:(UIWebView *)webView +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { } -- (void)webViewDidFinishLoad:(UIWebView *)webView +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { if (_finishLoadEvent) { - NSDictionary *data = [self baseInfo]; - [self fireEvent:@"pagefinish" params:data domChanges:@{@"attrs": @{@"src":self.webview.request.URL.absoluteString}}]; + [self baseInfoWithCompletion:^(NSMutableDictionary *data) { + [self fireEvent:@"pagefinish" params:data domChanges:@{@"attrs": @{@"src":self.webview.URL.absoluteString}}]; + }]; } } -- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { if (_failLoadEvent) { - NSMutableDictionary *data = [self baseInfo]; - [data setObject:[error localizedDescription] forKey:@"errorMsg"]; - [data setObject:[NSString stringWithFormat:@"%ld", (long)error.code] forKey:@"errorCode"]; - - NSString * urlString = error.userInfo[NSURLErrorFailingURLStringErrorKey]; - if (urlString) { - // webview.request may not be the real error URL, must get from error.userInfo - [data setObject:urlString forKey:@"url"]; - if (![urlString hasPrefix:@"http"]) { - return; + [self baseInfoWithCompletion:^(NSMutableDictionary *data) { + [data setObject:[error localizedDescription] forKey:@"errorMsg"]; + [data setObject:[NSString stringWithFormat:@"%ld", (long)error.code] forKey:@"errorCode"]; + + NSString * urlString = error.userInfo[NSURLErrorFailingURLStringErrorKey]; + if (urlString) { + // webview.request may not be the real error URL, must get from error.userInfo + [data setObject:urlString forKey:@"url"]; + if (![urlString hasPrefix:@"http"]) { + return; + } } - } - [self fireEvent:@"error" params:data]; + [self fireEvent:@"error" params:data]; + }]; } } -- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType -{ - if (_startLoadEvent) { - NSMutableDictionary *data = [NSMutableDictionary new]; - [data setObject:request.URL.absoluteString ?:@"" forKey:@"url"]; - [self fireEvent:@"pagestart" params:data]; - } - return YES; +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { + if (_startLoadEvent) { + NSMutableDictionary *data = [NSMutableDictionary new]; + [data setObject:navigationAction.request.URL.absoluteString ?:@"" forKey:@"url"]; + [self fireEvent:@"pagestart" params:data]; + } + + decisionHandler(WKNavigationActionPolicyAllow); } @end