前言
在实际开发过程中,我们常会遇到微信分享、QQ分享、微博分享、微信支付、支付宝支付等诸如此类的需要唤醒第三方App的需求。但是在接入这些第三方SDK时,常见的两种手段,一种是使用URL Scheme,另外一种是使用Universal Links。
本文主要达到的目的:
- 了解 URL Scheme和 Universal Link
- 正确配置配置 URL Scheme,并使用 URL Scheme 唤醒第三方App
- 正确配置 Universal Links,并使用 Universal Links 唤醒第三方App
正文
URL Scheme
iOS 开发者都清楚一个概念,叫做沙盒机制,所以 APP 不能直接跨越自己的区域去访问别的存储空间的内容,但是在实际开发过程中,我们又不能完全避免去与其他 APP进行通信,所以long long ago,苹果就推出了一种方式叫做 URL Scheme来完成这一通信。
相关术语
CFBundleURLType
, 表示当前 App 的 scheme 记录,通过 scheme 可以在其他 App 中打开当前 App。
LSApplicationQueriesSchemes
, 这个字段是在iOS 9更细系统策略的时候被引入的,即 App 的白名单,主要用于限制 schemes 协议的访问。
以上两个字段,是使用 URL Scheme 的核心。CFBundleURLType
字端用于声明别人唤醒我们自己 App 的 scheme,LSApplicationQueriesSchemes
字端用于声明我们想要唤醒的 App 的 scheme。
配置 URL Scheme
-
在
Info.plist
文件中添加,设置我们自己的URL Scheme,测试时,我填写的 URL Scheme 为 “iOSKateDev”。
-
将我们添加的 URL Scheme 输入到 Safari 中(即在浏览器地址中输入: iOSKateDev:// ),校验我们的URL Scheme是否添加成功,打开如下图,即表示设置成功了。
做到这一步的话,如果我们只是想让第三方 App 打开或访问我们的 App 的话,这时候就可以把我们设置好的 URL Scheme 交给第三方 App了。如果还想打开或者访问别人的 App 的话,就需要继续下一步。
-
将我们想要访问的或者打开第三方 App,那么我们就需要在
Info.plist
中继续添加LSApplicationQueriesSchemes
,并设置第三方 App 的 URL Scheme。如下图:上图中添加的是微信的 URL Scheme。
-
既然添加成功了,我们可以使用以下 API 来测试是否能正常打开。
UIApplication.shared.open(URL(string: "wechat://")!, options: [:], completionHandler: **nil**)
- 功成
常使用的URL Scheme
<key>LSApplicationQueriesSchemes</key>
<array>
<!--微信 URL Scheme白名单-->
<string>wechat</string>
<string>weixin</string>
<string>weixinULAPI</string>
<!-- QQ、Qzone URL Scheme白名单-->
<string>mqqopensdklaunchminiapp</string>
<string>mqqopensdkminiapp</string>
<string>mqqapi</string>
<string>mqq</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqconnect</string>
<string>mqqopensdkdataline</string>
<string>mqqopensdkgrouptribeshare</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkapi</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqqopensdkapiV4</string>
<string>mqzoneopensdk</string>
<string>wtloginmqq</string>
<string>wtloginmqq2</string>
<string>mqqwpa</string>
<string>mqzone</string>
<string>mqzonev2</string>
<string>mqzoneshare</string>
<string>wtloginqzone</string>
<string>mqzonewx</string>
<string>mqzoneopensdkapiV2</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapi</string>
<string>mqqbrowser</string>
<string>mttbrowser</string>
<string>tim</string>
<string>timapi</string>
<string>timopensdkfriend</string>
<string>timwpa</string>
<string>timgamebindinggroup</string>
<string>timapiwallet</string>
<string>timOpensdkSSoLogin</string>
<string>wtlogintim</string>
<string>timopensdkgrouptribeshare</string>
<string>timopensdkapiV4</string>
<string>timgamebindinggroup</string>
<string>timopensdkdataline</string>
<string>wtlogintimV1</string>
<string>timapiV1</string>
<!--新浪微博 URL Scheme白名单-->
<string>sinaweibohd</string>
<string>sinaweibo</string>
<string>sinaweibosso</string>
<string>weibosdk</string>
<string>weibosdk2.5</string>
<!--支付宝 URL Scheme白名单-->
<string>alipay</string>
<string>alipayshare</string>
<!--钉钉 URL Scheme白名单-->
<string>dingtalk</string>
<string>dingtalk-open</string>
<!--企业微信-->
<string>wxwork</string>
<string>wxworkdebug</string>
<string>wxworkrdm</string>
<string>wxworkrelease</string>
<!--抖音-->
<string>douyinopensdk</string>
<string>douyinsharesdk</string>
<string>snssdk1128</string>
<!--Linkedin URL Scheme白名单-->
<string>linkedin</string>
<string>linkedin-sdk2</string>
<string>linkedin-sdk</string>
<!--易信 URL Scheme白名单-->
<string>yixin</string>
<string>yixinopenapi</string>
<!-- instagram URL Scheme白名单-->
<string>instagram</string>
<!-- whatsapp URL Scheme白名单-->
<string>whatsapp</string>
<!-- line URL Scheme白名单-->
<string>line</string>
<!--Facebook URL Scheme白名单-->
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
<!--Kakao URL Scheme白名单-->
<!--注:以下第一个参数需替换为自己的kakao appkey-->
<!--格式为 kakao +"kakao appkey"-->
<string>kakaofa63a0b2356e923f3edd6512d531f546</string>
<string>kakaokompassauth</string>
<string>storykompassauth</string>
<string>kakaolink</string>
<string>kakaotalk-4.5.0</string>
<string>kakaostory-2.9.0</string>
<!-- pinterest URL Scheme白名单-->
<string>pinterestsdk.v1</string>
<!--Tumblr URL Scheme白名单-->
<string>tumblr</string>
<!--印象笔记-->
<string>evernote</string>
<string>en</string>
<string>enx</string>
<string>evernotecid</string>
<string>evernotemsg</string>
<!--有道云笔记-->
<string>youdaonote</string>
<string>ynotedictfav</string>
<string>com.youdao.note.todayViewNote</string>
<string>ynotesharesdk</string>
<!--Google+-->
<string>gplus</string>
<!--Pocket-->
<string>pocket</string>
<string>readitlater</string>
<string>pocket-oauth-v1</string>
<string>fb131450656879143</string>
<string>en-readitlater-5776</string>
<string>com.ideashower.ReadItLaterPro3</string>
<string>com.ideashower.ReadItLaterPro</string>
<string>com.ideashower.ReadItLaterProAlpha</string>
<string>com.ideashower.ReadItLaterProEnterprise</string>
<!--VKontakte-->
<string>vk</string>
<string>vk-share</string>
<string>vkauthorize</string>
<!--Twitter-->
<string>twitter</string>
<string>twitterauth</string>
</array>
常见问题
-
控制台报错:
error: "This app is not allowed to query for scheme xxxx"
解决方案:检查
LSApplicationQueriesSchemes
中是否正确添加要打开的 App 的 Scheme。 -
URL Scheme
和LSApplicationQueriesSchemes
都正确配置了,依旧打不开想要打开的第三方 App?解决方案:
- 检查两个字端是否真的正确配置了,例如把想打开的第三方 App 的 Scheme 设置到了
URL Types
中; - 由于
URL Scheme
是自定义的协议,所以可能有两个或者多个 App 的 Scheme 设置的一样,这时候根据系统的规则,它会打开最先安装的那个;
- 检查两个字端是否真的正确配置了,例如把想打开的第三方 App 的 Scheme 设置到了
-
当第三方 App 想打开我们的 App,并且向我们 App,传递一些参数时,我们怎么接收这些参数?
解决方案:常见的 URL Scheme 传值,会这么使用:“scheme://parameter=xxx”。我们在 AppDelegate 的如下方法中获取对应参数。
optional func application( _ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool
Universal Links
Universal Link 是苹果公司在 WWDC 上提出的iOS 9 的新特性之一。Universal Link类似于深层链接,能够方便的通过打开一个HTTPS
链接来直接启动您的客户端应用。
以下是苹果对它介绍:
Seamlessly link to content inside your app, or on your website in iOS 9 or later. With universal links, you can always give users the most integrated mobile experience, even when your app isn’t installed on their device.
配置 Universal Link
-
将域名添加
SSL
证书; -
为需要被打开App添加Associated Domains,如下图:
以上的截图是用 Xcode 自动管理证书的操作流程。
- 准备一个apple-app-site-association的文件,文件格式如下:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
该文件的主要内容在于details
字段中,这个字段对应的是一个列表,列表中每个对象都描述了可以使用通用链接的 App (即appID
字段),以及 App 支持的路径列表(paths
字段)。
appID
字段的规则为:teamID + “.” + Bundle id
path
字端的规则为:* 表示 通配符,只要在该文件所在域名之下的所有地址,均可通过通用链接唤醒 App。建议不直接使用域名 + 通配符来设置 App 支持的路径。
注意: 该文件的文件名不要有后缀名。
-
将编辑好的
apple-app-site-association
文件上传到域名的根目录或者 .well-known目录下(苹果建议是 .well-known目录)。 -
回到 Xcode 中,使用已在
apple-app-site-association
文件中注册的路径来填写,操作如下:
注意: 填写的内容是: “applinks:”+域名+已注册的路径,不需要填写 https。如:
applinks:help.wechat.com/app/
-
检验 Universal Link 是否正常
常见检验方案有如下几种:
- 将 Universal Link 复制到备忘录中,查看长按的显示内容,如果出现在XX中打开,即正常。如下图,使用微信的 Universal Link,长按会显示【在"微信"中打开】。
- 在 Safari 中输入 Universal Link,查看显示内容,如出现是否打开XX入口,即正常,如下图,仍是使用微信的 Universal Link举例,会显示【在"微信"应用中打开】
- 使用苹果提供的测试工具,苹果官方提供的测试工具地址
-
检验正常了,😄😄😄😄😄😄
常见问题
-
已经按照文档配置了,但是还是访问不了,我该肿么办?
解决方案:
- 是否添加了APP 支持 Universal Link,详见步骤2;
- 查看域名是否正确配置 SSL 证书,(如果你是阿里云的用户,阿里云提供的免费证书好像就可以正确配置);
- 查看上传的文件是否带有后缀名;
- 查看
apple-app-site-association
的链接是否带端口号; - 检查
apple-app-site-association
中的数据是否为正确的 JSON 格式; - 查看配置的 Univeral Link 是否与
apple-app-site-association
中的path具有一致性; - 删除 APP,重装试一试,
apple-app-site-association
中的设置只在 APP 第一次安装或者更新时才会被苹果拉取;