UIWebView 適用於iOS8.0如下的系統版本 iOS原生沒有提供js直接調用OC的方式,只能經過UIWebView的UIWebViewDelegate協議方法來作攔截,並在這個方法中,根據url來調用OC方法;html
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
複製代碼
// 是否容許加載網頁,也可獲取js要打開的url,經過截取此url可與js交互
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *urlString = [[request URL] absoluteString];
urlString = [urlString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSArray *urlComps = [urlString componentsSeparatedByString:@"://"];
NSLog(@"urlString=%@---urlComps=%@",urlString,urlComps);
return YES;
}
// 開始加載網頁
- (void)webViewDidStartLoad:(UIWebView *)webView {
NSURLRequest *request = webView.request;
NSLog(@"webViewDidStartLoad-url=%@--%@",[request URL],[request HTTPBody]);
}
// 網頁加載完成
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSURLRequest *request = webView.request;
NSURL *url = [request URL];
if ([url.path isEqualToString:@"/normal.html"]) {
NSLog(@"isEqualToString");
}
NSLog(@"webViewDidFinishLoad-url=%@--%@",[request URL],[request HTTPBody]);
NSLog(@"%@",[self.webView stringByEvaluatingJavaScriptFromString:@"document.title"]);
}
// 網頁加載錯誤
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSURLRequest *request = webView.request;
NSLog(@"didFailLoadWithError-url=%@--%@",[request URL],[request HTTPBody]);
}
複製代碼
#import <WebKit/WebKit.h>
- (instancetype)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
複製代碼
咱們大多使用第一種方式,這也是文檔中默認的一種方式。git
//頁面開始加載時調用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation
{
NSLog(@"頁面開始加載時調用。 2");
}
//內容返回時調用,獲得請求內容時調用(內容開始加載) -> view的過渡動畫可在此方法中加載
- (void)webView:(WKWebView *)webView didCommitNavigation:( WKNavigation *)navigation
{
NSLog(@"內容返回時調用,獲得請求內容時調用。 4");
}
//頁面加載完成時調用
- (void)webView:(WKWebView *)webView didFinishNavigation:( WKNavigation *)navigation
{
NSLog(@"頁面加載完成時調用。 5");
}
//請求失敗時調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
NSLog(@"error1:%@",error);
}
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
NSLog(@"error2:%@",error);
}
//在請求發送以前,決定是否跳轉 -> 該方法若是不實現,系統默認跳轉。若是實現該方法,則須要設置容許跳轉,不設置則報錯。
//該方法執行在加載界面以前
//Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Completion handler passed to -[ViewController webView:decidePolicyForNavigationAction:decisionHandler:] was not called'
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
//容許跳轉
decisionHandler(WKNavigationActionPolicyAllow);
//不容許跳轉
// decisionHandler(WKNavigationActionPolicyCancel);
NSLog(@"在請求發送以前,決定是否跳轉。 1");
}
//在收到響應後,決定是否跳轉(同上)
//該方法執行在內容返回以前
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
//容許跳轉
decisionHandler(WKNavigationResponsePolicyAllow);
//不容許跳轉
// decisionHandler(WKNavigationResponsePolicyCancel);
NSLog(@"在收到響應後,決定是否跳轉。 3");
}
//接收到服務器跳轉請求以後調用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation
{
NSLog(@"接收到服務器跳轉請求以後調用");
}
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
NSLog(@"webViewWebContentProcessDidTerminate");
}
複製代碼
NSString *str = [self.webview stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"postStr('%@','%@');",str1,str2]];
複製代碼
[self.wkWebView evaluateJavaScript:[NSString stringWithFormat:@"postStr('%@')", @"true"] completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"==%@----%@", result, error);
}];
複製代碼
在須要接受參數值的js界面實現以下方法:github
function postStr(str1, str2){
alert(str1, str2); //接收到的值」;
//...code
}
複製代碼
js是不能執行oc代碼的,可是能夠變相的執行,js能夠將要執行的操做封裝到網絡請求裏面,而後oc攔截這個請求,獲取url裏面的字符串解析便可。(攔截URL) 好比darkangel://。方法是在html或者js中,點擊某個按鈕觸發事件時,跳轉到自定義URL Scheme構成的連接,而OC中捕獲該連接,從中解析必要的參數,實現JS到OC的一次交互。好比頁面中一個a標籤,連接以下: <a href="darkangel: smslogin?username="12323123&code=892845"">短信驗證登陸</a href="darkangel:>
在該方法中,捕獲該連接,而且返回NO(阻止本次跳轉),從而執行對應的OC方法。web
/*
* 方法的返回值是BOOL值。
* 返回YES:表示讓瀏覽器執行默認操做,好比某個a連接跳轉
* 返回NO:表示不執行瀏覽器的默認操做,這裏由於經過url協議來判斷js執行native的操做,確定不是瀏覽器默認操做,故返回NO
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
//標準的URL包含scheme、host、port、path、query、fragment等
NSURL *URL = request.URL;
if ([URL.scheme isEqualToString:@"darkangel"]) {
if ([URL.host isEqualToString:@"smsLogin"]) {
NSLog(@"短信驗證碼登陸,參數爲 %@", URL.query);
return NO;
}
}
return YES;
}
複製代碼
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
//能夠經過navigationAction.navigationType獲取跳轉類型,如新連接、後退等
NSURL *URL = navigationAction.request.URL;
//判斷URL是否符合自定義的URL Scheme
if ([URL.scheme isEqualToString:@"darkangel"]) {
//根據不一樣的業務,來執行對應的操做,且獲取參數
if ([URL.host isEqualToString:@"smsLogin"]) {
NSString *param = URL.query;
NSLog(@"短信驗證碼登陸, 參數爲%@", param);
//不容許跳轉
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
//容許跳轉
decisionHandler(WKNavigationActionPolicyAllow);
NSLog(@"%@", NSStringFromSelector(_cmd));
}
複製代碼
附:個人博客地址瀏覽器