原生app与h5的哪点事

892 阅读6分钟

描述:本文对原生app与h5交互中遇到的一些问题,进行归纳与总结,将持续更新

目录

  • h5如何触发原生app的方法
  • 原生触发如何触发h5的方法
  • Universal Link 打开APP
  • 小程序打开app

一,h5如何触发原生app的方法

1,检测当前访问h5的游览器为ios还是安卓,我调用的是一下的方法

export function versions () {
    var u = navigator.userAgent
    return {
        trident: u.indexOf('Trident') > -1,
        presto: u.indexOf('Presto') > -1,
        webKit: u.indexOf('AppleWebKit') > -1,
        gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1,
        mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/),
        ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
        android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1,
        iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1,
        iPad: u.indexOf('iPad') > -1,
        webApp: u.indexOf('Safari') === -1
    }
}

2,与原生约定调用方法以及需要传递的参数,点击进行调用

也可传json字符串,由原生进行解析内部的参数

二,原生触发如何触发h5的方法

  • 如果你只是h5页面,并没有使用其他框架,则不需要做处理
  • 以vue框架为例,我们需要在mounted里面将原生需求触发的方法暴露出去

三,Universal Link 打开APP

需求:

  • app分享出去的页面,微信打开,点击打开按钮
  • 如果已经安装了App,通过链接可以打开App
  • 如果没有安装App,则前往下载App

iOS可以在微信手百中使用Universal Link,安卓由于版本太多存在兼容问题,建议引导到外部游览器,进行打开

1,IOS

配置apple-app-association

究竟哪些的url会被识别为Universal Link,全看这个apple-app-association文件 Apple Document UniversalLinks.html

  • 你的域名必须支持Https
  • 域名根目录下放这个文件apple-app-association,不带任何后缀
  • 文件为json保存为文本即可
  • json按着官网要求填写即可

知乎的 apple-app-association 文件

将配置好的文件放到根目录或者.well-known目录下

为了统一WAP&APP,为了通用链接的效果

Universal Link的域名其实是一个没有实际页面的域名,也就是说https://xxx.xxx.xxx/view/*这个url,如果没安装APP因此触发WebView继续跳转原地址,会直接404。处理很简单,重定向一下(服务器端重定向)

配置iOS App工程

开发者中心证书打开Associated Domains

工程配置Associated Domains

将你apple-app-association所在域名配置进去

给你的工程编写App被唤醒后的处理逻辑

#pragma mark Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webUrl = userActivity.webpageURL;
        [self handleUniversalLink:webUrl]; // 转化为App路由
    }
    return YES;
}

以下是我项目中的url,有兴趣的朋友,访问下

window.location.href = 'https://applinks.hosjoy.com/dfx/jumplink?link=' + 跳转路由

前面是域名,后面是唤起app打开对应的页面的路由

我在服务器端对这个域名进行了重定向,如果访问为404的时候,跳转到AppStore对应的页面进行app下载,否则直接唤起app,跳转到指定页面

2,安卓

在wap中唤起app其实应用最最广泛的并不是Universal Link,而是直接Schema跳转

location.href = 'schema://xxxx'

并且一般各大APP都会给自己做一套路由体系,这样其实可以直接在schema头后面对接路由体系,做到一行schema定位打开任意App内功能界面

给你的工程编写App被唤醒后的处理逻辑

(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    if ([[url absoluteString] hasPrefix:@"schema://"]) {
        [[WKDispatcher sharedInstance] operationObjectFromRouteURL:[url absoluteString]];//路由
        return YES;
    }
}

如果安装了APP才能支撑跳转这种Schema Url,如果没安装APP就没任何效果

在开头已经写了,由于安卓版本太多存在兼容问题,建议引导到外部游览器,进行打开

外部游览器打开页面可以是当前页面也可以是一个新页面,可根据游览器的内核做相对应的判断,我这边操作打开的是一个新页面, 直接调用

window.location.href = 'schema://showB2bpage?route=' + 打开页面的路由

如下图:

如果存在对应的app, 提示打开,如果没有,则无任何反应


大家想看特别详细的内容,推荐这篇 Universal Link 打开APP前端部署采坑记

总结:Schema无法在微信手百等特殊UA信息里面打开app,只能使用外部游览器打开。iOS可以在微信手百中使用Universal Link,安卓由于版本太多存在兼容问题,建议引导到外部游览器,进行打开

四,小程序跳转App

需求:

  • app分享小程序信息卡片,打开小程序
  • 小程序点击返回按钮,打开app

操作步骤:

第一步:

(1)确认APP和小程序在同一个开放平台账号可以直接完成跳转

(2)非一个开发平台下的APP和小程序关联后才支持跳转

可在“管理中心-移动应用-应用详情-关联小程序信息”,为通过审核的移动应用发起关联小程序操作

第二步:

原生APP端:

需要创建WXEntryActivty,实现IWXAPIEventHandler接口,重写onResp方法。注意Acitvity需要在Manifest文件中声明 android:exported="true",这样才可以被外部唤起

public void onResp(BaseResp resp) {
    if (resp.getType() == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
        WXLaunchMiniProgram.Resp launchMiniProResp = (WXLaunchMiniProgram.Resp) resp;
        String extraData =launchMiniProResp.extMsg; // 对应下面小程序中的app-parameter字段的value
    }
}

第三步:

小程序端:

通过app分享消息卡片,打开小程序,场景值是1036,根据项目的需求,在小程序中获得场景值进行返回app按钮的判断显示

小程序获取场景值

App({
    onLaunch: function (options) {
        console.log("[onLaunch] 本次场景值:", options.scene)
    },
    onShow: function (options) {
        console.log("[onShow] 本次场景值:", options.scene)
    }
})

第四步:

小程序端:

需要将 button 组件 open-type 的值设置为 launchApp。如果需要在打开 APP 时向 APP 传递参数,可以设置 app-parameter 为要传递的参数。通过 binderror 可以监听打开 APP 的错误事件

<button class="server_button" open-type="launchApp" app-parameter="wechat" binderror="launchAppError">打开APP</button>

扩展

再下一步的需求是多个App跳转一个小程序,再分别返回不同的App;一个App跳转不同的小程序,接受不同的返回内容。

从App拉起小程序页面的路径是可以带参数的,我们就利用这个参数判断是从那个App跳到小程序的。

例如:

名称为a的App跳转路径为:

"pages/index/index?type=appA"

名称为b的App跳转路径为:

"pages/index/index?type=appB"

小程序端接收参数:

onLoad: function (options) {
    console.log(options.type); //app传递过来的参数 可以判断a或者b
}