1.OC與JS互動之UIWebView
######建立一個UIWebView 並載入
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20)];
_webView.delegate = self;
_webView.scrollView.bounces = NO;
/ 新增 webiview
[self.view addSubview:self.webView];
// 載入請求
// 1.URL
NSURL *url = [NSURL URLWithString:HOME_URL];
// 2.建立請求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.載入請求
[self.webView loadRequest:request];
複製程式碼
######UIWebView delegate 協議方法
//網頁即將開始載入
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
//網頁開始載入
- (void)webViewDidStartLoad:(UIWebView *)webView;
//網頁載入完成
- (void)webViewDidFinishLoad:(UIWebView *)webView;
//網頁載入失敗
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
//UIWebView自帶了一個方法, 可以直接呼叫JS程式碼(轉化為string型別的js程式碼)
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
//例如修改id為‘html’標籤內部的text屬性
[web stringByEvaluatingJavaScriptFromString:@"document.getElementById('html').innerText='修改內容'"];
//也可以執行多行js程式碼
[web stringByEvaluatingJavaScriptFromString:@"var div = document.getElementById('html'); div.innerText = '修改內容'"];
複製程式碼
####// JS呼叫OC
一,js裡面直接呼叫方法
方法1
程式碼如下
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@",request.URL );
if ([[request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/stats/index?orgId=",PR_AppDotNetAPIBaseURLString]]) {
[self menuLeftBarButton];
} else {
[self setDefaultBackButton];
[self setRightButton];
}
return YES;
}
複製程式碼
在這個網頁即將載入的方法裡面做一些網址的擷取,可以做一些相應的處理,對某些特定的網址做不同的處理。至於返回YES 還是NO 就根據你們的需求做處理
方法2
在網頁載入完成之後使用蘋果推薦的JavaScriptCore
對於有引數傳遞的也是有兩種方法獲取,詳細見圖
程式碼如下
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if ([[webView.request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/stats/index?orgId=",PR_AppDotNetAPIBaseURLString]]) {
self.title = @"我的機構";
} else {
self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
if ([[webView.request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/newstats/hot/",PR_AppDotNetAPIBaseURLString]]) {
[self touchToDetail];
}
[self invokeJS];
}
- (void)invokeJS {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"orgBuyCoin"] = ^() {
BuyCoinViewController *vc = [[BuyCoinViewController alloc] initWithNibName:@"BuyCoinViewController" bundle:nil];
vc.whicePay = @"BCPay";
vc.productType = @"4";
vc.title = @"機構購買學幣";
[self.navigationController pushViewController:vc animated:YES];
};
context[@"buyMembers"] = ^() {
NSNumber *MemberCount = [[NSNumber alloc] init];
NSArray *args = [JSContext currentArguments];
MemberCount = (NSNumber *)args[0];
JSValue *this = [JSContext currentThis];
NSLog(@"this8888888888888: %@",this);
NSLog(@"-------End Log-------");
BuyMembersViewController *vc = [[BuyMembersViewController alloc] initWithNibName:@"BuyMembersViewController" bundle:nil];
//返回的
NSLog(@"-----MemberCount:%@", MemberCount);
vc.MemberCount = MemberCount;
[self.navigationController pushViewController:vc animated:YES];
};
}
複製程式碼
二,js裡面通過物件呼叫方法 這裡以微信和支付寶支付為例子 這裡要藉助 JSExport 可以制定一個協議
@protocol JSLivingDelegate <JSExport>
/**
* 支付寶支付
*
* @param ali_pay_data 支付資料
* @param ali_order 訂單
*/
JSExportAs(ali_pay,
- (void)ali_sub:(id)ali_pay_data order:(id)ali_order
);
//微信支付
JSExportAs(wx_pay,
- (void)wxpay_sub:(NSString *)appId
nonceStr:(NSString *)nonceStr
outTradeNo:(NSString *)outTradeNo
package:(NSString *)package
partnerid:(NSString *)partnerid
paySign:(NSString *)paySign
prepayid:(NSString *)prepayid
signTyp:(NSString *)signTyp
timeStamp:(NSString *)timeStamp
);
@end
遵循協議實現對應的OC方法就行了
複製程式碼
//OC呼叫JS
方法1
程式碼如下 iOS 7之前 [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"addressCallBack('%@','%@','%@','%@');",provincecid,province,citycid,city]];
方法2
NSString * method = @"dolike";
JSValue * function = [self.context objectForKeyedSubscript:method];
//這裡面的a,b,c就是OC呼叫JS的時候給JS傳的引數
[function callWithArguments:@[a,b,c]];
複製程式碼
2.OC與JS互動之WKWebView
######建立一個WKWebView 並載入
self.webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 20, kScreenWidth, kScreenHeight-20) configuration:config];
self.webView.scrollView.bounces = NO;
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
複製程式碼
######WKWebView中的三個代理方法
1 WKNavigationDelegate
// 頁面開始載入時呼叫
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 當內容開始返回時呼叫
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 頁面載入完成之後呼叫
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 頁面載入失敗時呼叫
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
頁面跳轉的代理方法有三種,分為(收到跳轉與決定是否跳轉兩種)
// 接收到伺服器跳轉請求之後呼叫
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation: (WKNavigation *)navigation;
// 在收到響應後,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在傳送請求之前,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
複製程式碼
2 WKUIDelegate
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
/ 介面彈出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
// 介面彈出確認框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
// 介面彈出輸入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
複製程式碼
3 WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message;
複製程式碼
//JS呼叫OC
也可以擷取網址這裡就不在累述 在建立web的時候 self.webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 20, kScreenWidth, kScreenHeight-20) configuration:config]; 配置 config 對js 的方法進行類似註冊的操作
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
//初始化偏好設定屬性:preferences
config.preferences = [WKPreferences new];
//The minimum font size in points default is 0;
config.preferences.minimumFontSize = 10;
//是否支援JavaScript
config.preferences.javaScriptEnabled = YES;
//不通過使用者互動,是否可以開啟視窗
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
[config.userContentController addScriptMessageHandler:self name:@"AppModel"];
[config.userContentController addScriptMessageHandler:self name:@"ConfirmAccepts"];
[config.userContentController addScriptMessageHandler:self name:@"ChuanPhone"];
複製程式碼
然後在代理做對應的處理和引數的接收
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",message.body);
if ([message.name isEqualToString:@"AppModel"]) {
[self showMsg:@"我收到js的AppModel"];
}
if ([message.name isEqualToString:@"ConfirmAccepts"]) {
NSString *info = [NSString stringWithFormat:@"你好 %@, 很高興見到你",message.body];
[self showMsg:info];
}
if ([message.name isEqualToString:@"ChuanPhone"]) {
NSArray *array = message.body;
NSString *info = [NSString stringWithFormat:@"這是我的手機號: %@, %@ !!",array.firstObject,array.lastObject];
[self showMsg:info];
}
}
複製程式碼
//OC 呼叫JS
//方法 setName
[webView evaluateJavaScript:@"setname('張三')" completionHandler:nil];
//此處 setname為JS定義的方法名, 內部 ‘張三’為傳給JS的引數。 如果setname方法需要傳入一個json或者array等非字元引數, 需要用format方法將其轉為string型別,在呼叫evaluate方法。例如
NSString * para = [NSString stringWithFormat:@"setname('%@')",json];
複製程式碼
希望能夠幫助你,有什麼問題歡迎留言。