浅析URLScheme在iOS中存在的意义

iOS是一个自闭的系统,应用之间是不能互相存储,读取文件。为了满足应用的通讯,苹果使用了URL Scheme来实现了这个功能。通过各个APP设计的符合苹果的统一规范的URL Scheme,Url Scheme 是可以用来在各种应用之间传递信息。

URLScheme在iOS中的定义和理解

URLScheme是为方便app之间互相调用而设计的。你可以通过一个类似URL的链接,通过系统的OpenURl来打开该app,并可以传递一些参数。每个URL必须能唯一标识一个APP,如果你设置的URL与别的APP的URL冲突,此时,你的APP不一定会被调用起来,原因是当APP在安装的时候就已经在系统里面注册了此APP的URL Scheme,如果你的一致但是是后安装的,那么系统不会调用你的APP,因为你的APP设置的URL scheme被覆盖了。

简单分析

以微信的为示例,大家都知道微信SDK中集成了登录,分享,支付等功能,这几个也是平时大家用到比较多的功能,都是需要跳转到微信app中进行操作,URLScheme就是作用于应用间互相通讯的,那么我们不妨看看微信在登录,分享,支付的时候分别传递了什么样的信息。

由于URLScheme会互相覆盖,后安装者会覆盖前一个安装者。我们创建一个简单的空白应用,把这个应用的URLScheme设置成**和微信一样,让系统以为后面安装的就是微信。我们可以在这个app中截取URLScheme,然后看看传递的是什么东西。

创建工程,设置工程的URLScheme

在项目里info.plist (非test里面的info.plist)并选择 右键 Open As – Source Code:
加入如下源码:

CFBundleURLTypesCFBundleURLSchemesweixin

就会生成和微信app相同的URLScheme。就是weixin。

在AppDelegate.m里面截取跳转过来的URLScheme,app接收urlScheme传值时会响应此方法

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{

//显示截取的urlscheme

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"接收到的urlScheme" message:url.absoluteString delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];

[alert show];

return YES;

}

运行手机上有微信登录,分享,支付的app,点击微信的登录,分享或者支付。看看会发生什么

在iphone找一个有微信的登录,支付,分享的工程的app,在app中做相应的操作。

image
image

我们会发现点解微信登录的时候,提示的不是打开微信,而是打开我自己创建的app(get_scheme_str),点击打开会看到我们想看到的。

image

能看到,在登录的过程中,实际上Scheme是携带一些参数的url。上图的url是

weixin://app/wxa932d071d0f12af2/auth/?scope=snsapi_message%2Csnsapi_userinfo%2Csnsapi_friend%2Csnsapi_contact&state=xxx&supportcontentfromwx=8191

稍微调整一下数据格式

weixin://app/wxa932d071d0f12af2/auth/?scope=snsapi_message,snsapi_userinfo,snsapi_friend,snsapi_contactstate=xxxsupportcontentfromwx=8191

接过微信sdk的朋友一定可以非常简单的看出来这里面其实传递的就是四个参数,分别的是微信后台申请的appid,scope,state,supportcontentfromwx,后面两个经实验固定形式就可以,第一个是appid参数,第二个是登录微信,需要的权限,字段是固定的,用逗号分隔开,这个可以去微信开发者中心查看。也就是说实际上我们只需要填写appid就可以跳转到微信app中进行登录操作。

同样的将你要用到微信登录的app的Scheme设置成在微信后台申请成功的appid。这样通过跳转到微信登录,点击登录后,微信同样会根据这个Scheme返回到相应的app,并携带一串auth认证返回的结果.

image

wxa932d071d0f12af2://oauth?code=071MME2c1SUdTr0j2B4c1k4D2c1MME2F&state=xxx

可以看到是以为wxa932d071d0f12af2://为协议的Scheme,携带code的参数。我们同样可以在AppDelegate中截取到这个code,然后根据code请求固定的api,拿到登录账号的数据。就可以完成登录。

同样的道理,微信的分享,支付也是一样的。通过以上的方式,我们可以拿到微信分享的Scheme是

weixin://app/wxa932d071d0f12af2/sendreq/?

分享回调的Scheme是

wxa932d071d0f12af2://platformId=wechat

支付的也是一样,支付的URLScheme是

weixin://app/wxa932d071d0f12af2/pay/?partnerId=1455924902&prepayId=wx20170830135454e7f54637ae0987672641&package=Sign%3DWXPay&nonceStr=dd4ftd1vdz9x36haqivffa922sn4ijei&timeStamp=1504072494&signType=SHA1&supportcontentfromwx=8191

支付回调的Scheme是

wxa932d071d0f12af2://pay/?returnKey=(null)&ret=-2

对比官方SDK

这里就以参数最多的支付为示例,首先我们看看微信开放者平台中调起支付的参数介绍和说明

image

上面的支付URLScheme经过简单的处理后

weixin://app/wxa932d071d0f12af2/pay/?

partnerId=1455924902

prepayId=wx20170830135454e7f54637ae0987672641

package=Sign=WXPay

nonceStr=dd4ftd1vdz9x36haqivffa922sn4ijei

timeStamp=1504072494

signType=SHA1

supportcontentfromwx=8191

我们可以很容易的看到,URLScheme中携带的数据,和微信官方的数据是一样的。url中只是多了一个签名方式和supportcontentfromwx。经测试,这两个数据基本上是固定的。那么我们可以大胆的猜测,在微信官方SDK中发起微信的支付时候,其实最底层还是通过URLScheme的方式进行数据互传的。它通过固定的协议头加上不同的参数来实现应用不同的逻辑。

你可能感兴趣的:(浅析URLScheme在iOS中存在的意义)