实现的
效果就是上边那样:首先通过webview 进行网络请求 然后进行显示。
然后点击下一页的按钮 通过js的响应显示另一个网页
最后通过下一页的按钮可以返回到首页。
本文仅仅是h5跟ios 的交互的入门 所以没有做细致的描述。
首先先说一下思路:我的项目中是那样的:首先h5从后台拿到数据,然后我请求h5的界面,然后通过h5的按钮进行选择,通过ios控制按钮到那个界面。
这个小demo不涉及数据传输,只是界面的交互。
1 我自己写了两个小网页。
代码如下
首页的indexPage.html
<!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(\"%@\")",@""];
// 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 = ; //2.
self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(, , self.view.bounds.size.width, self.view.bounds.size.height/) 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 == ) {//电话
[self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
//TODO
NSLog(@"%@ %@",response,error);
}];
} if (sender.tag == ) {//名字 [self.wkWebView evaluateJavaScript:@"alertName('小红')" completionHandler:nil];
} if (sender.tag == ) {//信息
[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:%; 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(['', 'Go Climbing This Weekend !!!'])
} </script> </head> <!--网页具体内容-->
<body>
<br/> <div>
<label>小黄:</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
与君共勉