描述:本文对原生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,与原生约定调用方法以及需要传递的参数,点击进行调用
二,原生触发如何触发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按着官网要求填写即可
将配置好的文件放到根目录或者.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=' + 打开页面的路由
如下图:
大家想看特别详细的内容,推荐这篇 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
}