一、混合开发是什么?

混合开发,是指在开发一款App产品的时候,为了提高效率、节省成本而利用原生与H5的开发技术的混合应用。通俗点来说,这就是网页的模式,通常由“H5云网站+APP应用客户端”两部份构成。

混合开发是一种取长补短的开发模式,原生代码部分利用插件或者其它框架为H5提供容器,程序主要的业务实现、界面展示都是利用与H5相关的技术进行实现的。很多APP都是利用混合开发模式而成的。

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

web网页和ios,android进行交互(原理)
  1. web网页调用ios和android
  2. web页面发送一个假的请求, 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网页
先在网页上准备一个获得结果的回调函数
当原生需要传值给网页时,向打开网页的窗口动态插入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];
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐