實現的html
效果就是上邊那樣:首先經過webview 進行網絡請求 而後進行顯示。html5
而後點擊下一頁的按鈕 經過js的響應顯示另外一個網頁java
最後經過下一頁的按鈕能夠返回到首頁。ios
本文僅僅是h5跟ios 的交互的入門 因此沒有作細緻的描述。web
首先先說一下思路:個人項目中是那樣的:首先h5從後臺拿到數據,而後我請求h5的界面,而後經過h5的按鈕進行選擇,經過ios控制按鈕到那個界面。網絡
這個小demo不涉及數據傳輸,只是界面的交互。app
1 我本身寫了兩個小網頁。iview
代碼以下異步
首頁的indexPage.htmlasync
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button onclick="next()">nextPage(下一頁)</button>
</body>
<script>
alert("123");
function next(){
WOSS.goForward("下一頁","http://127.0.0.1:8020/HelloHBuilder/index2.html");
}
</script>
</html>
第二個界面的html index2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<br />
<label>這是第二個網頁,歡迎你跳轉成功了</label>
<button onclick="returnFirst()">返回首頁</button>
</head>
<body>
</body>
<script>
function returnFirst(){
WOSS.goHome("返回","http://127.0.0.1:8020/HelloHBuilder/index1.html#");
}
</script>
</html>
2 進行ios代碼的編寫
(1)建立Navigation.h
#import <UIKit/UIKit.h> @interface LSNavigation : UINavigationController @end
Navigation.m
#import "LSNavigation.h" @implementation LSNavigation @end
(2)appDelegate的設置
appDelegate.h
#import <UIKit/UIKit.h> #import "LSNavigation.h" @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) LSNavigation *baseNavigationController; @end
appdelagete.m
#import "AppDelegate.h" #import "LSNavigation.h" #import "LSWebVC.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.baseNavigationController = [[LSNavigation alloc] init]; self.window.rootViewController = self.baseNavigationController; LSWebVC *vc = [[LSWebVC alloc]init]; [self.baseNavigationController pushViewController:vc animated:YES]; return YES; }
(3)建立:LSwebViewVC用來顯示加載webView
webVIewVC.h
#import <UIKit/UIKit.h> #import <JavaScriptCore/JavaScriptCore.h> @interface LSWebVC : UIViewController @property (nonatomic,strong) UIWebView *webView; //@property (nonatomic,assign) BOOL needRefresh; @property (nonatomic,copy) NSString *webTitle; @property (nonatomic,copy) NSString *webUrl; @end
webViewVC.m
#import "LSWebVC.h" #import "LSInterActive.h" @interface LSWebVC()<UIWebViewDelegate> @property (nonatomic,strong) JSContext *context; @end @implementation LSWebVC -(void)viewDidLoad { _webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0,([UIScreen mainScreen].bounds.size.width ) , ([UIScreen mainScreen].bounds.size.height))]; self.view.backgroundColor = [UIColor yellowColor]; self.title = self.webTitle; self.webView.delegate = self; [self.view addSubview:self.webView]; if(!self.webUrl) { self.webUrl=@"http://127.0.0.1:8020/HelloHBuilder/indexPage.html"; }else{ self.webUrl = [self.webUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; } NSURL *url = [NSURL URLWithString:self.webUrl]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20]; [self.webView loadRequest:request]; } -(void)webViewDidFinishLoad:(UIWebView *)webView { self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; self.context.exceptionHandler = ^(JSContext *con, JSValue *exception) { NSLog(@"exception==========================================================:%@", exception); con.exception = exception; }; //設置對象別名 LSInterActive *interactive = [[LSInterActive alloc] init]; self.context[@"WOSS"] = interactive; } @end
(4)建立進行點擊交互的類(用於存放一些點擊事件交互用)
LSINterActive.h
#import <Foundation/Foundation.h> #import <JavaScriptCore/JavaScriptCore.h> @protocol FCInteractiveProtocol <JSExport> //1.1前進 //goForward(title,forwardUrl) - (void)go:(NSString *)title forward:(NSString *)url; - (void)go:(NSString *)title home:(NSString *)url; @end @interface LSInterActive : NSObject<FCInteractiveProtocol> @end
LSInterActive.m
#import "LSInterActive.h" #import "LSWebVC.h" #import "LSNavigation.h" #import "AppDelegate.h" @implementation LSInterActive //下一頁 -(void)go:(NSString *)title forward:(NSString *)url { NSLog(@"FCInteractive-------goForward:%@,%@",title,url); //當前是異步線程 dispatch_async(dispatch_get_main_queue(), ^{ AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; LSNavigation *navi = delegate.baseNavigationController; LSWebVC *nextVc = [[LSWebVC alloc] init]; nextVc.webTitle = title; nextVc.webUrl = url; [navi pushViewController:nextVc animated:YES]; }); } //返回主頁 - (void)go:(NSString *)title home:(NSString *)url{ NSLog(@"FCInteractive-------goHome:%@,%@",title,url); //當前是異步線程 dispatch_async(dispatch_get_main_queue(), ^{ AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; LSNavigation *navi = delegate.baseNavigationController; UIViewController *vc = navi.viewControllers[0]; if ([vc isKindOfClass:[LSWebVC class]]) { LSWebVC *firstVc = (LSWebVC *)vc; // firstVc.needRefresh = YES; } [navi popToRootViewControllerAnimated:YES]; }); } @end
這樣的話就能夠了。簡單的實現了交互。若有不足,歡迎指出 本人郵箱673658917@qq.com
------------------------補充分界線-------------------------------------------------------------------------
最近又在看oc與h5交互,因此又補充一點,就是 例如你在原生的界面登陸成功以後怎麼給html界面把值傳過去?
我這邊採用的方式是:通知傳值的方式
思路: 在webviewVC的界面初始化的時候就要把通知加上 而後 登陸成功以後 發送通知 將值傳給h5
//添加一個通知 等着須要傳值給html的時候就用這個通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveNoti:) name:@"sendMyUserID" object:nil];
通知方法實現
//利用通知的方法 給h5傳值 - (void)receiveNoti:(NSNotification*)noti{ NSString *jsString = [NSString stringWithFormat:@"sendUserPhone(\"%@\")",@"55586"]; // NSLog(@"登陸成功js-------%@",jsString); [self.context evaluateScript:jsString]; }
發送通知
-(void)btnClicked:(UIButton*)sender{ [[NSNotificationCenter defaultCenter]postNotificationName:@"sendMyUserID" object:nil]; }
這樣的話就能夠了哦,oc跟h5 相互船傳值就是這麼簡單。
想要demo的加我 qq 673658917@qq.com
---------------------------------------------------------------------------------------------------------------------------------------------------------------------以上是第一種方法,也是利用原生的 uiwebview進行實現的,步驟簡單,我如今項目中使用的方法就是方法1. 可是ios8以後 蘋果推出了 wkWebview 比uiwebview 佔用內存更小,運行速度更快,如今獻上 wkwebview的使用方法,供你們參考。---------------------------------------------------------------------------------------
之前的時候並無深刻研究過webview,最近正好失戀了,就研究一下吧。
之前的時候一直在用uiwebview 總是感受佔不少的內存,可是沒有時間處理,因此就一直拖着。
最近發現了wkwebview 這個是ios8以後出來的,就在#import <WebKit/WebKit.h>這個類裏邊就包含了這個wkwebview這個類,wkwebview繼承於uiview 特色:佔用內存更少了,速度更快了。
看一下wkwebview的特性:
1.性能 穩定性 功能方面有很大的提升(最直觀的就是體如今佔用的內存上邊)。
2.容許js的Nitro庫加載並使用(uivieqview中限制)
3.支持更多的html5特性
4.高達60fps的滾動刷新頻率以及內置手勢
5.將uiviewviewdelegate與uiwenview重構成了14個類和3個協議 (查看蘋果官方文檔https://developer.apple.com/reference/webkit)
下邊開始講使用了哦
準備工做:
1.設置oc代碼
2.設置html代碼
3.運行
oc代碼:
// // ViewController.m // OC與JS交互之WKWebView // // Created by user on 16/8/18. // Copyright © 2016年 rrcc. All rights reserved. // #import "ViewController.h" #import <WebKit/WebKit.h> @interface ViewController () <WKScriptMessageHandler> @property (nonatomic, strong) WKWebView *wkWebView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1. WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.preferences.minimumFontSize = 18; //2. self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config]; [self.view addSubview:self.wkWebView]; //3. // NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; // NSURL *baseURL = [[NSBundle mainBundle] bundleURL]; // [self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL]; NSURL *url = [[NSURL alloc]initWithString:@"http://127.0.0.1:8020/h5AndOCTest/myIndex.html"]; NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url]; [self.wkWebView loadRequest:request]; //4. WKUserContentController *userCC = config.userContentController; //JS調用OC 添加處理腳本 [userCC addScriptMessageHandler:self name:@"showMobile"]; [userCC addScriptMessageHandler:self name:@"showName"]; [userCC addScriptMessageHandler:self name:@"showSendMsg"]; } //網頁加載完成以後調用JS代碼纔會執行,由於這個時候html頁面已經注入到webView中而且能夠響應到對應方法 //oc調用h5,經過按鈕的點擊事件進行響應 - (IBAction)btnClick:(UIButton *)sender { if (!self.wkWebView.loading) { if (sender.tag == 123) {//電話 [self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) { //TODO NSLog(@"%@ %@",response,error); }]; } if (sender.tag == 234) {//名字 [self.wkWebView evaluateJavaScript:@"alertName('小紅')" completionHandler:nil]; } if (sender.tag == 345) {//信息 [self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','週末登山真是件愉快的事情')" completionHandler:nil]; } } else { NSLog(@"the view is currently loading content"); } } #pragma mark - WKScriptMessageHandler //h5調用oc 根據h5那邊傳遞過來的數據進行響應的彈框顯示 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { NSLog(@"%@",NSStringFromSelector(_cmd)); NSLog(@"%@",message.body); if ([message.name isEqualToString:@"showMobile"]) { [self showMsg:@"我是下面的小紅 手機號是:18870707070"]; } if ([message.name isEqualToString:@"showName"]) { NSString *info = [NSString stringWithFormat:@"你好 %@, 很高興見到你",message.body]; [self showMsg:info]; } if ([message.name isEqualToString:@"showSendMsg"]) { NSArray *array = message.body; NSString *info = [NSString stringWithFormat:@"這是個人手機號: %@, %@ !!",array.firstObject,array.lastObject]; [self showMsg:info]; } } - (void)showMsg:(NSString *)msg { [[[UIAlertView alloc] initWithTitle:nil message:msg delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; } @end
html代碼:
<html> <!--描述網頁信息--> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>小黃</title> <style> *{ font-size: 50px; } .btn{height:80px; width:80%; padding: 0px 30px; background-color: #0071E7; border: solid 1px #0071E7; border-radius:5px; font-size: 1em; color: white} </style> <script> function clear() { document.getElementById('mobile').innerHTML = '' document.getElementById('name').innerHTML = '' document.getElementById('msg').innerHTML = '' } //OC調用JS的方法列表 function alertMobile() { //這裏已經調用過來了 可是搞不明白爲何alert方法沒有響應 //alert('我是上面的小黃 手機號是:13300001111') document.getElementById('mobile').innerHTML = '我是上面的小黃 手機號是:13300001111' } function alertName(msg) { //alert('你好 ' + msg + ', 我也很高興見到你') document.getElementById('name').innerHTML = '你好 ' + msg + ', 我也很高興見到你' } function alertSendMsg(num,msg) { //window.alert('這是個人手機號:' + num + ',' + msg + '!!') document.getElementById('msg').innerHTML = '這是個人手機號:' + num + ',' + msg + '!!' } //JS響應方法列表 function btnClick1() { window.webkit.messageHandlers.showMobile.postMessage(null) } function btnClick2() { window.webkit.messageHandlers.showName.postMessage('xiao黃') } function btnClick3() { window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!']) } </script> </head> <!--網頁具體內容--> <body> <br/> <div> <label>小黃:13300001111</label> </div> <br/> <div id="mobile"></div> <div> <button class="btn" type="button" onclick="btnClick1()">小紅的手機號</button> </div> <br/> <div id="name"></div> <div> <button class="btn" type="button" onclick="btnClick2()">打電話給小紅</button> </div> <br/> <div id="msg"></div> <div> <button class="btn" type="button" onclick="btnClick3()">發短信給小紅</button> </div> </body> </html>
oc代碼中 的文件路徑 根據實際狀況定 ,若是是在項目中本地的就用我註釋的方法,若是是在電腦桌面上就能夠用沒有註釋的路徑,根據實際狀況來。
就這樣就完成了。
想要源碼的 聯繫我郵箱 673658917@qq.com
或者是加我qq 673658917
與君共勉