前言
上一篇《h5随意调起原生页面》中已经提到,app在运营过程当中,很多时候需要做一些推广活动,同时需要通过各种途径发布消息出去,比如通过app通知、公众号推送、群发短信。在这里,我们来说说如何通过短信里的链接(短链接)跳转到app指定的页面。
短链接是什么?
短链接,通俗来说,就是将长的URL网址,通过程序计算等方式,转换为简短的网址字符串。
在短信里加入短链接原因有很多,其中有一种是因为字数限制导致无法在一条信息里表达完整的意思,不得不针对比较长的URL经过算法压缩成短链。
网上短链生成器有很多,这里推荐一个新浪短短网址生成器短网址,地址http://www.yuekaihua.com/blog/arrangement_04.html?name=yuekaihua
生成之后的样子为http://t.cn/RTdGR9Z。
实际上,用户点击短链之后,系统会调起浏览器,短链经过解析之后就会变回原来的模样去访问,如果想要调起app,实际上就是浏览器(app)与你的应用(app)之间的通信了。
如何通信?
URL Scheme 与 openURL
关于这两个东西这里就不做解释了,网上太多太多。今天的重点是如果通过浏览器调起我们自己的app并且跳转到指定的页面,传入合适的参数。
在上一篇《h5随意调起原生页面》中,描述的场景是app内通过webview调起我们想要的页面,现在换成了app外调起内部想要的页面,这个方案是不是还可行?答案显然是的,请看下图:
duanlian.png对比上一篇,只不过是信息的来源发生了变化,其余的不变。变化的地方为:
- 使用URL Scheme后,app会通过
application:openURL:options:
(ios2-9.0)或者application:openURL:sourceApplication:annotation:
(ios9.0以上)进行监听 - h5上通过iframe打开约定的地址
由于是使用URL Scheme,js传送过来的数据上要发生变化:
myScheme://xxx.com?params={'type':'1','controll':'XXXViewController','params':'{'xxx':'xxx'}'}
说明:
myScheme 为自己给app定义的Scheme
xxx.com 标识是有短链或外部调用内部特定页面
params 需要解析的json数据,即上一篇中的data
实现过程
app:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
if (url == nil) {
return YES;
}
return [self handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if (url == nil) {
return YES;
}
return [self handleOpenURL:url];
}
- (BOOL)handleOpenURL:(NSURL *)url
{
NSString *urlstr = url.absoluteString;
if ([urlstr hasPrefix:@"yuekaihua"]) {
//外部调起
NSString *formatUrl = [urlstr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSArray *defineArray = [formatUrl componentsSeparatedByString:@"params="];
if (defineArray.count > 1) {
NSString *paramJson = defineArray[1];
paramJson = [paramJson changeJsonStringToTrueJsonString];//将单引换成双引
NSDictionary *params = [paramJson dictionaryWithJsonString];//转化为Dictionary
[self outsiteJump:params];
}
}
return YES;
}
- (void)outsiteJump:(NSDictionary *)params
{
id currVc = [self curViewController];//当前屏幕viewcontroller
if (currVc) {
if ([currVc isKindOfClass:[ViewController class]]) {
ViewController *currentVc = (ViewController *)currVc;
MYLPageJumpHepler *pageJump = [[MYLPageJumpHepler alloc] initWithParent:currentVc];
[pageJump clientDefineAction:params];
}else{
//不做处理
}
}else{
//当app没有运行时,先保存数据,在主页面再跳转
[[PINCache sharedCache] setObject:params forKey:@"OutSideJumpExtData"];
}
}
h5 关键js
<script>
$(function(){
new FastClick(document.body);
//ios safari调起app页面
$(".safariBtn").on("click",function(){
var ua = navigator.userAgent.toLowerCase();
var schemeIOS = getUrlParam('schemeIOS');
var schemeAdr = getUrlParam('schemeAdr');
var config = {
/*scheme:必须*/
scheme_IOS: schemeIOS === null ? "yuekaihua://yuekaihua.com?params={'type':'1','controll':'TestViewController','params':{'type':'1','entity':{'UserEntity_userInfo':{'birthday':'1988-09-09','name':'hahaha'}}}}" : schemeIOS,
scheme_Adr: schemeAdr === null ? "yuekaihua://yuekaihua/openApp" : schemeAdr,
};
var scheme = ua.indexOf('os') > 0 ? config.scheme_IOS : config.scheme_Adr;
OpenAppBySchema(scheme);
});
});
function getUrlParam(name) {
//构造一个含有目标参数的正则表达式对象
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
//匹配目标参数
var r = window.location.search.substr(1).match(reg);
//返回参数值
if (r != null)
return unescape(decodeURI(r[2])); //scheme url作为参数需要先编码,所以这里要先decodeURI解码,然后再unescape解码
return null;
}
function OpenAppBySchema(scheme) {
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') > -1 && (ua.indexOf('os 8') == -1
|| ua.indexOf('os 7') == -1
|| ua.indexOf('os 6') == -1
|| ua.indexOf('os 5') == -1)) {
var schemeLinkOpen = document.getElementById('schemeLinkOpen');
if (!schemeLinkOpen) {
schemeLinkOpen = document.createElement('a');
schemeLinkOpen.id = 'schemeLinkOpen';
schemeLinkOpen.style.display = 'none';
document.body.appendChild(schemeLinkOpen);
}
schemeLinkOpen.href = scheme;
// 执行click
schemeLinkOpen.dispatchEvent(customClickEvent());
}
var iframeObj = document.createElement("iframe");
if (iframeObj != null) {
iframeObj.setAttribute("style", "height:0px;width:0px;display:none;")
iframeObj.setAttribute("src", scheme);
document.body.appendChild(iframeObj);
document.body.removeChild(iframeObj);
}
}
function customClickEvent() {
var clickEvent;
if (window.CustomEvent) {
clickEvent = new window.CustomEvent("click", {
canBubble: true,
cancelable: true
}
);
} else {
clickEvent = document.createEvent('Event');
clickEvent.initEvent('click', true, true);
}
return clickEvent;
}
</script>
最后
短链跳转到APP这里就结束了,加上上一篇,在这里整理出了demo,有兴趣的可以下载看看:
DefinedOpenVC
相关回顾
网友评论