前言
上一篇《h5隨意調(diào)起原生頁(yè)面》中已經(jīng)提到,app在運(yùn)營(yíng)過(guò)程當(dāng)中,很多時(shí)候需要做一些推廣活動(dòng),同時(shí)需要通過(guò)各種途徑發(fā)布消息出去,比如通過(guò)app通知、公眾號(hào)推送、群發(fā)短信。在這里,我們來(lái)說(shuō)說(shuō)如何通過(guò)短信里的鏈接(短鏈接)跳轉(zhuǎn)到app指定的頁(yè)面。
短鏈接是什么?
短鏈接,通俗來(lái)說(shuō),就是將長(zhǎng)的URL網(wǎng)址,通過(guò)程序計(jì)算等方式,轉(zhuǎn)換為簡(jiǎn)短的網(wǎng)址字符串。
在短信里加入短鏈接原因有很多,其中有一種是因?yàn)樽謹(jǐn)?shù)限制導(dǎo)致無(wú)法在一條信息里表達(dá)完整的意思,不得不針對(duì)比較長(zhǎng)的URL經(jīng)過(guò)算法壓縮成短鏈。
網(wǎng)上短鏈生成器有很多,這里推薦一個(gè)新浪短短網(wǎng)址生成器短網(wǎng)址,地址http://www.yuekaihua.com/blog/arrangement_04.html?name=yuekaihua生成之后的樣子為http://t.cn/RTdGR9Z。
實(shí)際上,用戶點(diǎn)擊短鏈之后,系統(tǒng)會(huì)調(diào)起瀏覽器,短鏈經(jīng)過(guò)解析之后就會(huì)變回原來(lái)的模樣去訪問(wèn),如果想要調(diào)起app,實(shí)際上就是瀏覽器(app)與你的應(yīng)用(app)之間的通信了。
如何通信?
URL Scheme 與 openURL
關(guān)于這兩個(gè)東西這里就不做解釋了,網(wǎng)上太多太多。今天的重點(diǎn)是如果通過(guò)瀏覽器調(diào)起我們自己的app并且跳轉(zhuǎn)到指定的頁(yè)面,傳入合適的參數(shù)。
在上一篇《h5隨意調(diào)起原生頁(yè)面》中,描述的場(chǎng)景是app內(nèi)通過(guò)webview調(diào)起我們想要的頁(yè)面,現(xiàn)在換成了app外調(diào)起內(nèi)部想要的頁(yè)面,這個(gè)方案是不是還可行?答案顯然是的,請(qǐng)看下圖:

對(duì)比上一篇,只不過(guò)是信息的來(lái)源發(fā)生了變化,其余的不變。變化的地方為:
- 使用URL Scheme后,app會(huì)通過(guò)
application:openURL:options:(ios2-9.0)或者application:openURL:sourceApplication:annotation:(ios9.0以上)進(jìn)行監(jiān)聽(tīng) - h5上通過(guò)iframe打開(kāi)約定的地址
由于是使用URL Scheme,js傳送過(guò)來(lái)的數(shù)據(jù)上要發(fā)生變化:
myScheme://xxx.com?params={'type':'1','controll':'XXXViewController','params':'{'xxx':'xxx'}'}
說(shuō)明:
myScheme 為自己給app定義的Scheme
xxx.com 標(biāo)識(shí)是有短鏈或外部調(diào)用內(nèi)部特定頁(yè)面
params 需要解析的json數(shù)據(jù),即上一篇中的data
實(shí)現(xiàn)過(guò)程
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"]) {
//外部調(diào)起
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];//轉(zhuǎn)化為Dictionary
[self outsiteJump:params];
}
}
return YES;
}
- (void)outsiteJump:(NSDictionary *)params
{
id currVc = [self curViewController];//當(dāng)前屏幕viewcontroller
if (currVc) {
if ([currVc isKindOfClass:[ViewController class]]) {
ViewController *currentVc = (ViewController *)currVc;
MYLPageJumpHepler *pageJump = [[MYLPageJumpHepler alloc] initWithParent:currentVc];
[pageJump clientDefineAction:params];
}else{
//不做處理
}
}else{
//當(dāng)app沒(méi)有運(yùn)行時(shí),先保存數(shù)據(jù),在主頁(yè)面再跳轉(zhuǎn)
[[PINCache sharedCache] setObject:params forKey:@"OutSideJumpExtData"];
}
}
h5 關(guān)鍵js
<script>
$(function(){
new FastClick(document.body);
//ios safari調(diào)起app頁(yè)面
$(".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) {
//構(gòu)造一個(gè)含有目標(biāo)參數(shù)的正則表達(dá)式對(duì)象
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
//匹配目標(biāo)參數(shù)
var r = window.location.search.substr(1).match(reg);
//返回參數(shù)值
if (r != null)
return unescape(decodeURI(r[2])); //scheme url作為參數(shù)需要先編碼,所以這里要先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;
// 執(zhí)行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>
最后
短鏈跳轉(zhuǎn)到APP這里就結(jié)束了,加上上一篇,在這里整理出了demo,有興趣的可以下載看看:
DefinedOpenVC
相關(guān)回顧