ios:
一、应用跳转原理
应用跳转到另一个应用应该是很常见的需求,比如第三方登录,微信或者支付宝支付,就需要用到应用间跳转的技术,做过的可能知道我们需要配置一个URL Schemes:
其实这个URL Schemes就是应用间的一个通讯协议,如同http协议一样。
举个栗子:"http://127.0.0.1/path?parameter=参数"
“http://”:协议类型
127.0.0.1:服务器ip地址
“ parameter =参数”:请求的参数
iOS中苹果是如何管理应用跳转的呢?其实就是UIApplication下面这个 的API
<pre>
- (BOOL)openURL:(NSURL*)url;
</pre>
它的一些我们非常熟悉的用法:
//拨打系统电话
<pre>
NSURL *url = [NSURL URLWithString:@"tel://10086"];
[[UIApplication sharedApplication] openURL:url];
</pre>
//发送系统短信
<pre>
NSURL *url = [NSURL URLWithString:@"sms://1383838438"];
[[UIApplication sharedApplication] openURL:url];
</pre>
二、实现两个app间的跳转
创建两个示例应用,Test1和Test2,现在需要实现从Test1跳转到Test2中
1、在被跳转的TestDemo配置一个协议scheme,这里命名为test(名字可随意配置,当然最好是英文并且跟你项目相关)
targets -> info -> URL Types ->URL Scheme ->填写协议
2、在Test2中实现一个跳转方法,方法内部代码如下:
<pre>
NSURL *url = [NSURL URLWithString:@"myTest://"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
else{
NSLog(@"没有安装应用");
}
</pre>
针对iOS9.0以后,需要配置协议白名单,用过微信或支付宝支付的肯定很清楚,也都配过。
在Test2的info.plist文件中增加一个LSApplicationQueriesSchemes
字段,把它设置为数组类型,并配置需要跳转的协议名单
三、跳转到指定界面
想要跳转到指定界面,必然是上一个app告诉下一个app(被跳转的app)需要跳转到哪个界面,而如何告诉它这里便涉及到两个app的通信。我们从上面可以知道,两个app之间的跳转只需要配置一个scheme,然后通过UIApplication
调用它的对象方法openURL:
即可实现,除此之外再也没有实现任何代码了。而这之间是如何通信的呢?
答案依然是协议,请看下面步骤:
- 1、在"myTest://"协议后面的域名加上一些字段用来标记需要跳转的界面
进入测试界面方法体如下
<pre>
NSURL *url = [NSURL URLWithString:@"myTest://test"];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}else{
NSLog(@"没有安装应用"); }
</pre>
- 2、来到被跳转的应用Test的AppDelegate监听其代理方法
application:handleOpenURL:
//当应用程序将要被其他程序打开时,会先执行此方法,并传递url过来
iOS9.0之前用下面的方法
application:openURL:options:
//注意适配:9.0后用这个方法:
<pre>
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
NSLog(@"url:%@",url.absoluteString);
NSLog(@"host:%@",url.host);
if ([url.host isEqualToString:@"test"])
{
NSLog(@"进入测试界面");
}
return YES;
}
</pre>
web页面判断手机里是否安转应用的原理就是:首先试着打开手机端某个app的本地协议;如果超时就转到app下载页,下载该app。
下面说说
URL scheme 概述
URL scheme 的作用
客户端应用可以向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如车辆详情页、订单详情页、消息通知页、促销广告页等等。也可以执行某些指定动作,如订单支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。
URL scheme 的格式
客户端自定义的 URL 作为从一个应用调用另一个的基础,遵循 RFC 1808 (Relative Uniform Resource Locators) 标准。这跟我们常见的网页内容 URL 格式一样。
一个普通的 URL 分为几个部分,scheme
、host
、relativePath
、query
。
比如:http://www.baidu.com/s?rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709
,这个URL中,scheme
为 http
,host
为www.baidu.com
,relativePath
为 /s
,query
为 rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709
。
一个应用中使用的 URL 例子(该 URL 会调起车辆详情页):uumobile://mobile/carDetail?car_id=123456
,其中 scheme
为 uumobile
,host
为mobile
,relativePath
为 /carDetail
,query
为 car_id=123456
。
Scheme定义Activity
1)在androidmanifest.xml中定义scheme
<!-- 启动页 --> <activity android:name="com.qiyuan.congmingtou.activity.SplashActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- 要想在别的App上能成功调起App,必须添加intent过滤器 --> <intent-filter> <!-- 协议部分,随便设置 --> <data android:scheme="cmt" android:host="splash"/> <!-- 下面这几行也必须得设置 --> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <action android:name="android.intent.action.VIEW" /> </intent-filter> </activity>这样我们便定义了能够接受scheme请求的activity实例,当网页或者是android代码发送这种规则scheme的请求的时候就能够吊起SplashActivity了。
2.网页中Html代码和js代码
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<title>this's a demo</title>
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
</head>
<body>
<div>
<a id="J-call-app" href="javascript:;" class="label">立即打开>></a>
<input id="J-download-app" type="hidden" name="storeurl" value="http://m.chanyouji.cn/apk/chanyouji-2.2.0.apk">
</div>
<script>
(function(){
var ua = navigator.userAgent.toLowerCase();
var t;
var config = {
/*scheme:必须*/
scheme_IOS: 'IfInstalledCongMingTou://congmingtou',
scheme_Adr: 'cmt://splash',
download_url: document.getElementById('J-download-app').value,
timeout: 600
};
function openclient() {
var startTime = Date.now();
var ifr = document.createElement('iframe');
ifr.src = ua.indexOf('os') > 0 ? config.scheme_IOS : config.scheme_Adr;
ifr.style.display = 'none';
document.body.appendChild(ifr);
var t = setTimeout(function() {
var endTime = Date.now();
if (!startTime || endTime - startTime < config.timeout + 200) {
window.location = config.download_url;
} else {
}
}, config.timeout);
window.onblur = function() {
clearTimeout(t);
}
}
window.addEventListener("DOMContentLoaded", function(){
document.getElementById("J-call-app").addEventListener('click',openclient,false);
}, false);
})()
</script>
</body>
</html>
如果我们要用于实现对scheme的解析,然后做出相应的动作,比如请求scheme跳转登录页面,要在SplashActivity中做写相应的代码:
public class SplashActivity extends Activity{ public Activity mContext = null; public void onCreate(Bundle b) { super.onCreate(b); mContext = this; Uri uri = getIntent().getData(); if (uri != null) { List<String> pathSegments = uri.getPathSegments(); String uriQuery = uri.getQuery(); Intent intent; if (pathSegments != null && pathSegments.size() > 0) { // 解析SCHEME if (someif) { dosomething(); } else { // 若解析不到SCHEME,则关闭NativeAppActivity; finish(); } } else { finish(); } } else { finish(); } } }
这里简单说一下,我们可以通过Intent对象获取调用的scheme的host等信息
this.getIntent().getScheme();//获得Scheme名称 this.getIntent().getDataString();//获得Uri全部路径
通过服务器下发跳转路径跳转相应页面
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("uumobile://yongche/123123123")));
这里的”uumobile://yongche/123123123”就是服务器下发的跳转路径,当我们执行startActivity的时候就会调起SpalshActivity,然后我们通过在SpalshActivity解析scheme的内容,跳转相应的页面
总结:
android中的scheme是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;
通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。