Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面

大家好,我是OB。
不积小流,无以成江海。今天给大家分享一下web基础使用

一:加载HTML的几种方式

    /**
     *  1,加载网络html
     */
    NSString * surl = @"http://192.168.3.134:7080/toCompanyTouch";
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:surl]];
    [self.wkwebView loadRequest:request];
     /**
     *  2,加载本地html 资源(内容)
     */
    NSURL * url =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"testH5" ofType:@"html"];
    NSString * htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    [self.wkwebView loadHTMLString:htmlString baseURL:url];   
    /**
     *  3,加载本地html url
     */
    NSURL * url2 =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];
    [self.wkwebView loadFileURL:url2 allowingReadAccessToURL:url2];

Native和js交互没有想象中那么不着边际

二:UIWebView与JS交互

首先使用到 <JavaScriptCore/JavaScriptCore.h>框架中的 JSContextJSExport对象。
JSContext Native和JS交互时,连接两者的上下文,
JSExport Native和JS交互协议。(实现方法调用时必须实现的协议)

然后通过KVC的方式获得 JSContext(上线时可能有风险,还可以通过KVO的方式获得)

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    JSContext * context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // self 是装有 UIWebView的控制器,并且它遵守了 JSExport 协议
    //把self这个对象放到上下文中,通过VC这个key可以找到self这个对象
    [context setObject:self forKeyedSubscript:@"VC"];
}

在然后就可以在JS页面中使用这个VC了,VC能对应上OC中那个controller
不要忘记在UIViewController中遵守并实现JSExport

//遵守协议
@protocol JS_OCCOnnectProtocolInWeb <JSExport>
- (void)testLog:(NSDictionary*)dict;
@end
@interface UIWeb_VC () <UIWebViewDelegate,JS_OCCOnnectProtocolInWeb>
@property UIWebView * webView;
@end

@implementation UIWeb_VC
//实现协议方法
- (void)testLog:(NSDictionary*)dict
{
    NSLog(@"---testLog--");
    NSLog(@"dict=[%@]",dict);
}
@end

最后在js中调用就方便了

<button onclick="VC.testLog({'page':'testVC'})">UIWeb测试</button>

打印信息如下

2017-12-06 15:18:58.645195+0800 TestHybriod[2378:1026324] ---testLog--
2017-12-06 15:18:58.646071+0800 TestHybriod[2378:1026324] dict=[{
    page = testVC;
}]

三:WKWebView与JS交互

OC版本可以看我下一篇文章,有惊喜!!!

1,WebKitWKWebView使用的是Safari的浏览器内核,在性能上高于UIWebView
wk的交互需要用到 MessageHandler,在实例化WKWebView时配置一下WKUserContentController,并且遵守 WKScriptMessageHandler 协议实现他的方法

- (void)viewDidLoad {
    [super viewDidLoad];
    WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];
    config.userContentController =[[WKUserContentController alloc]init];
    //意思是将名字为 ocWkModth 的方法注册到js中
    [config.userContentController addScriptMessageHandler:self name:@"ocWkModth"];
    self.wkwebView = [[WKWebView alloc]initWithFrame:self.view.boundsconfiguration:config];
}

WKScriptMessageHandler 协议的方法。在这里可以接收到js传来的参数

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    NSLog(@"body=[%@]",message.body);
    NSLog(@"name=[%@]",message.name);
    NSLog(@"frameInfo.absoluteString=[%@]",message.frameInfo.request.URL.absoluteString);
    
}

在JS中调用如下方法可以将信息传递到OC的 WKScriptMessageHandler 协议方法中


<a class="test-btn" onclick="window.webkit.messageHandlers.ocWkModth.postMessage({'page':'testVC','result':'success'})">测试</a>

打印信息如下

2017-12-06 14:24:47.955640+0800 TestHybriod[2047:784478] body=[{
    page = testVC;
    result = success;
}]
2017-12-06 14:24:47.955845+0800 TestHybriod[2047:784478] name=[ocWkModth]

源码-地址

四,其他粗暴的方法

在Native和js交互肯定是需要一个桥梁,在UIWebView中使用的是下面这个方法

webView.stringByEvaluatingJavaScript(from: "document.getElementById('index-kw').value = '1234';");

在WKWebView中使用的是

webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in
	NSLog("any=" + (any as! String));
}
 /*其实就是这个样子的,后面是swift的闭包*/ 
 webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';", completionHandler: nil);

这两个方法是有返回值的,返回值就是html5页面中 element的value(可以片面的理解为UILable的text),虽然这个方法能执行JavaScript的代码,但只局限为可操作的一些元素和方法,这里给大家解释一下js一些简单的方法

/*通过这个id可以得到某个元素或者标签*/
var lable_btn = document.getElementById('某个元素或者标签的id');
/*可以set和get元素或者标签的value*/  
lable_btn.value = 'value的值';
/*通过这个ClassName可以得到某个元素或者标签  的数组*/
var nodesInput = document.getElementsByClassName('input');
nodesInput[0].value = 'test';

在h5页面加载完成后,执行以下操作

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234';", completionHandler: nil);

/*其实就是这个样子的,后面是swift的闭包*/
 webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in
 /*any 其实就是返回值*/
        NSLog("any=" + (any as! String));
  }

}

效果如下,其中 index-kw 是百度收索框的元素 id,给这个id的value,赋值。出现如下效果
这就是一个简单的交互

这里写图片描述
但在实际开发中可能需要一些更高级的交互,这里没有使用网上的一些框架

/*这里可以监听和拦截 h5 页面的 alert*/
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        if message == "商量好的信息" {
            /*这里可以谈一个native的弹窗*/
            //UIAlertController ....
        }
}

五,其他的交互机制–拦截机制

H5页面跳转原生界面

1:项目配置

在 info 里面 添加 URL Schemes

我在里添加的是 com.sir.pppig

图二

然后在 appDegelate.m 中,监听

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    NSLog(@"----]");
    if (!url) {  return NO; }
    // 可以在这里处理打开APP后的 业务逻辑
    NSLog(@"new url= [%@]", url);
    return YES;
}
2:事件触发
A:浏览器触发

然后在浏览器中输入 com.sir.pppig://, 就可以打开APP了,

pne1

点击 open ,打开APP

B:在h5页面触发

在h5页面触发,

<a id="openApp" href="com.sir.pppig://">打开APP</a>
		      

六:iOS 9 通用链接(Universal Links)

在iOS9之前,我们通常只能使用scheme从浏览器、Safari中唤醒APP。还要检测是否安装了能够响应此scheme的APP,而且在某些地方可能会被禁用。

Universal Links是iOS9推出的一项功能,让APP能通过HTPP协议来启动APP。如果没有安装可以打开指定的网页

通用链接的简单使用
  1. 首先需要一个域名,且这个域名需要支持https。

  2. 需要在开发者中心做配置:找到对应的App ID,在Application Services列表里有Associated Domains一条,把它变为Enabled就可以了。

  3. 打开工程配置中的Associated Domains,在其中的Domains中填入你想支持的域名,必须以applinks:为前缀。

  4. 创建一个内容为json格式的文件,苹果将会在合适的时候,从我们在项目中填入的域名请求这个文件。这个文件名必须为apple-app-site-association,没有后缀名。

  5. 上传该文件到你的域名所对应的根目录或者.well-known目录下,这是为了苹果能获取到你上传的文件。上传完后,自己先访问一下,看看是否能够获取到,当你在浏览器中输入这个文件链接后,应该是直接下载apple-app-site-association文件。

开发中可能会遇到这样的需求:从Native跳转到H5页面需要将用户信息传递或者携带过去!!!有没有遇到过。反正我是遇到过!,还有可能要将js中的商品ID传给原生。这里就要用到一个强大的工具了,时间原因。请见我下一篇文章

具体使用和说明在我下一篇文章里面

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值