標籤:
上次學習的是OC調用JS,通過OC的代碼,操作JS的代碼,對JS代碼進行增刪改查,以及調用JS的方法;今天,學習下JS調用OC。
上次對WebView進行簡要的分析,今天就直接進主題,在iOS開發中,JS調用OC主要是通過下面這個函數來實現的:
#pragma mark - <UIWebViewDelegate>/** * 通過這個方法完成JS調用OC */-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ // 擷取請求資料 URL 資料 NSString *str = request.URL.absoluteString; NSLog(@"URL-String = %@",str);}
解析此函數:當webView開始請求資料的時候會調用此方法,並將請求參數傳給我們,我們通過 “request.URL.absoluteString” 屬性查看請求的URL地址;(JS內部可以自訂請求URL路徑)
我們可以利用這個函數,擷取請求行為,篩選行為並調用OC的方法。
當我瀏覽webView內部內容時,會列印請求路徑,如:
自己在學習JS之前,先瞭解HTML一些基本便簽,在HTML內部調用JS代碼
HTML代碼:
(CSS代碼就不列出了,CSS只為布局,這裡意義不大)
<body> <div id="name" align="center"> <input id="userName" placeholder="親輸入使用者名稱"/> </div> <div id="pwd" align="center"> <input id="password" placeholder="請輸入密碼" type="password"/> </div> <div id="login" align="center"> <button class="button">登入</button> </div> <br /><br /><br /> <div align="center"> <a href="http://www.baidu.com">百度一下</a> </div></body>
詳解:這裡通過HTML布局了一個簡易的登入介面
介面內布局”百度一下”, 一是:測試OC內的函數,擷取請求URL參數
二是:證明這是個網頁WebView,不是用OC實現的介面
介面效果如下:
JS代碼:
<body> <!-- 調用 javascript --> <script type="text/javascript"> <!-- 通過 id 擷取輸入框 --> var userName = document.getElementById(‘userName‘); var password = document.getElementById(‘password‘); <!-- 通過 id 擷取按鈕 --> var button = document.getElementById(‘login‘); <!-- 給按鈕的點擊加方法 --> button.onclick = function(){ <!-- 擷取輸入框內輸入的值 --> var name = userName.value; var pwd = password.value; if (!name | !pwd) { alert(‘使用者名稱或密碼為空白!‘); return; } <!-- href:Hypertext Reference的縮寫。意思是超文本引用 href 屬性的值可以是任何有效文檔的相對或絕對URL,包括片段標識符和JavaScript程式碼片段。 --> window.location.href = ‘text://loginAction:pwd:‘ + ‘?‘ + name + ‘?‘ + pwd; } </script></body>
詳解:這裡通過調用JS,擷取到網頁內部的輸入框及按鈕,得到輸入框內部輸入值;並監聽按鈕的點擊方法,在按鈕的點擊方法內部給予請求路徑,並把輸入框輸入的值拼接到請求URL後面,這樣,當按鈕被點擊時,OC內可以擷取到此請求URL,判斷URL的資料,調用OC的方法。
OC代碼:
這裡我是類比登陸,當使用者名稱和密碼一樣時,登陸成功(但二者都不可為空);
#pragma mark - <UIWebViewDelegate>/** * 通過這個方法完成JS調用OC * JS和OC互動的第三方架構:WebViewJavaScriptBridge */-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ // 擷取請求資料 URL 資料 NSString *str = request.URL.absoluteString; NSLog(@"requestURL-String = %@",str); // 擷取 ‘標記符‘ 所在的地區 NSRange range = [str rangeOfString:@"text://"]; // 如果找到資源 if (range.location != NSNotFound) { // 擷取標記符背景字元(方法名?使用者名稱?密碼) NSString *params = [str substringFromIndex:range.location + range.length]; // 利用 ? 切割字元,擷取每個參數 NSArray *subStrings = [params componentsSeparatedByString:@"?"]; // 第一個是方法名 NSString *methodStr = subStrings.firstObject; // 第二個是使用者名稱輸入框內的資料 NSString *userName = subStrings[1]; // 第三個是密碼輸入框內的資料 NSString *password = subStrings.lastObject; // 執行方法,並傳入參數(使用者名稱和密碼) [self performSelector:NSSelectorFromString(methodStr) withObject:userName withObject:password]; } return YES;}/** * 登陸方法 * * @param name 使用者名稱 * @param pwd 密碼 */-(void)loginAction:(NSString *)name pwd:(NSString *)pwd { // 這裡類比登陸,當使用者名稱 == 密碼時,登陸成功 if (![name isEqualToString:pwd]) { // 使用者名稱 != 密碼,登陸失敗,返回 UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:@"使用者名稱或密碼錯誤,請重新輸入" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:nil]; [alertVC addAction:cancel]; [self presentViewController:alertVC animated:YES completion:nil]; return; } // 登陸成功後,跳入下一個介面 SuccessViewController *svc = [[SuccessViewController alloc] init]; svc.userName = name; svc.password = pwd; [self presentViewController:svc animated:YES completion:nil];}
詳解:通過截取請求路徑URL,判斷請求行為,我這裡的URL拼接的方法是’loginAction:pwd:’並傳入兩個參數(使用者名稱和密碼),通過調用[self performSelector:NSSelectorFromString(xxx) withObject:xxx withObject:xxx];這個方法,執行請求參數內部的方法字串,和請求參數(注意:JS內部的方法名和OC內部需要被調用的方法名一定要保持一致,不然會出現未找到方法異常);
這裡是調用JS內部提示框:
這裡是通過OC代碼限制跳轉:
當使用者名稱和密碼相同時,跳轉下一個介面:
總結:這裡成功擷取webView內部輸入框的資料,並調用webView內部按鈕的點擊事件,完成簡易的登陸跳轉功能;方法和原理很簡單,一是通過JS設定按鈕點擊方法內部的屬性,二是用到webView內部的一個代理方法,擷取到按鈕點擊方法內部的請求資料,解析資料的結構,相應自己的方法!
iOS-JS調用OC