混合开发流程和桥接技术详解(WebViewJavaScriptBridge)

混合开发流程

前端流程

打包成app

但web页面写好后,执行打包程序

  1. 使用的路由,必须是hash路由
  2. 项目中使用的请求,必须是完整的路径,并且这个路径需要后台配置可以跨域
  3. 打包前需要设置打包出来的路径是相对路径
  4. 解决手机屏幕齐刘海的问题
  5. 执行打包(测试:本地打开打包好的项目,流程没问题,就可以执行下一步)
  6. 将项目包给ios, android开发人员

(实际上相当于在电脑上打开这个文件,需要能在本地打开打包好的index.html能展现可操作的完整页面)

  1. 本地只支持hash模式
  2. 本地需要请求完整路径,且涉及跨域
  3. 若做全屏的h5页面嵌套,可以用到安全高度计算的插件(‘safeAreaInsets’)
  4. 使得本地打开能请求到相对应的静态资源
部署到服务器上
  1. 路由可以使用hash也可以使用history
  2. 请求必须是相对于环境的
  3. 打包路径(hash可以使用相对路径和绝对路径)(history使用绝对路径)
  4. 解决手机屏幕齐刘海的问题。npm i safe-area-insets -S
  5. 执行打包给后台(history路由需要配置404的重定向)

原生开发流程

通常以ios为标准,安卓根据ios调整(减少前端工作量,减少不必要的对接)

#import <WebKit/WebKit.h>

// 获取窗口宽高
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;

//WKWebView *webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, width, height)];

// 禁止滚动
webview.scrollView.bounces = NO;

// html文件路径
// 本地前端包
NSString *path = [[NSBundle mainBundle] pathForResource:@"dist/index" ofType:@"html"];
// 线上前端页面,必须https协议
NSString *path = @"https://www.zhihu.com/question/54564198";

// 构建请求,让webview加载请求
// NSURL *url = [NSURL URLWithString:path];
NSURL *url = [[NSURL alloc] initFileUrlWithPath:path];

NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webview loadRequest:request];

[self.view addSubview:webview]

web网页和ios,android进行交互(原理)

web网页调用ios和android
  1. web页面发送一个假的请求
  2. ios,android拦截请求,解析是真请求还是假请求
    1. 真请求放行
    2. 假请求拦截,解析出真实的功能需求字段,
    3. 通过发布订阅,传递给相应文件,做出相应的操作

发送一个假请求,让原生开发拦截(该加请求的url路劲需要和ios,android设置的保持一致)

ios拦截请求

// 继承类MyURLProtocol,子类NSURLProtocol
// MyURLProtocol.h文件
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
@interface MyURLProtocol: NSURLProtocol



@end
// MyURLProtocol.m文件
#import "MyURLProtocol.h"
@implementation MyURLProtocol

// 手机app是否可以加载请求
+ (BOOL)canInitWithRequest:(NSURLRequest *)request{
    
    //拦截到请求后,获取请求的字符串
    NSString *path = request.URL.absoluteString;
    
    // 判断字符串是否以协商好的虚假协议开头(如emma://开头)
    if([path hasPrefix:@"emma://"]){
        // 这是个假请求
        // 获取该请求真实目的
        NSString *action = [path substringFromIndex:7];
        
        // 该文件不能调用一些原生功能,需要装有webview的视图文件才行,所以要将该请求字段传给视图文件
        // 文件间不能通信,用发布订阅(ios自带一个发布订阅)
        if([action isEqualToString:@"captureImage"]){
            // 发送消息,拍照
            [[NSNotificationCenter defaultCenter] postNotificationName:@"captureImage" object:nil userInfo:nil];
        }
        
        // 拦截掉该请求
        return NO;
    } else {
        // 真请求
        // 允许该请求通过
        return YES;
    }
}
    
@end

// 装有webview的页面(文件)
#import "MyURLProtocol.h"

// 注册MyURLProtocol,可以实现拦截
[NSURLProtocol registerClass:[MyURLProtocol class]];

// 订阅消息,拍照的消息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCaptureImage) name:@"captureImage" object:nil];

// 订阅拍照消息的处理函数
-(void)handleCaptureImage{
    // 拍照的操作
}

html发送假请求

<!-- // HTML文件发送假请求 -->
<a href="emma://captureImage">拍照</a>
<a href="emma://openweChart">打开微信</a>
<a href="emma://scan">扫一扫</a>
// js文件发送假请求
window.location.href = 'emma://captureImage';
ios,android传值给web网页
  1. 先在网页上准备一个获得结果的回调函数
  2. 当原生需要传值给网页时,向打开网页的窗口动态插入js代码,这段js代码就是调用回调函数的代码

web代码

import React, { useState } from 'react'
function WebView() {
 const [image, setimage] = useState('');
 
 const btnAction = () => {
     // 发送一个假的请求,触发原生
      window.location.href = 'emma://captureImage';
      
      // 在window设置了一个回调方法(模块化开发,ios只能找到window全局作用域,所以只能挂在window上)
      window.onCaptureImageCallback = (value) => {
          setimage(value)
      }
 }
 
 return (
 	<div>
     	<button onClick={btnAction}>拍照</button>
         <img src={image} />
     </div>
 )
}

ios代码

// webview的文件
// 需要将webview提升成全局变量(挂载webview的函数和处理发布订阅事件的函数是两个作用域)
@property (strong, nonatomic) WKWebView *webview;

// 事件处理函数中
// 向窗口注入js代码
NSString *jsMethod = [NSString stringWithFormat:@"window.onCaptureImageCallback('%@')", @"需要传给网页的值"];
[self.webview evaluateJavaScript:jsMethod completionHandler:nil];

WebViewJavaScriptBridge插件(桥接技术)

先出的ios的,后社区根据ios的bridge写了android的bridge。

ios桥接的git地址: https://github.com/marcuswestin/WebViewJavascriptBridge

android桥接的git地址: https://github.com/jesse01/WebViewJavascriptBridge

发布了3 篇原创文章 · 获赞 2 · 访问量 100
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览