最近搞微信授权登录,在开放平台创建app时发现需要配置Universal Links
,以前没这个玩应儿,就研究研究怎么搞。
Universal Links是什么
这个翻译过来就是通用链接
。如果设备里安装了你的app,用户点击一个Universal Links
链接时,会直接跳转到你的app,无需通过safari中间中转。如果设备里没有安装你的app,点击Universal Links
时,会在safari里打开你的链接。
Universal Links的一些特点
与URL scheme
相比,Universal Links
有以下特点。
Uique(独特). 不像url scheme,别人的app不能声明你的
Universal Links
,因为你自己app的Universal Links
都是指向你自己网站的标准http或者https链接。Secure(安全). 当用户安装你的应用程序时,iOS会检查你已上传到Web服务器的
apple-app-site-association
文件,以确保你的网站允许您的应用程序代表你的网站打开URL。只有你有权利创建和上传此文件到你自己的web服务器,因此你的网站与应用程序的关联是有安全保障的。Flexible(灵活). 即使未安装您的应用程序,
Universal Links
也可以使用。如果未安装您的应用程序,则按用户期望,点击指向您网站的链接可在Safari中打开内容。Simple(简单).
Universal Links
链接可以在app和网站都能生效Private(私人的). 其他应用程序可以与您的应用程序通信,而无需知道您的应用程序是否已安装。
注意
通用链接可让用户在点击WKWebView,UIWebView视图和Safari页面中的指向您网站的链接时打开您的应用程序,此外,这些链接还会导致调用openURL:,例如在Mail,Messages和其他应用程序中点击的链接。
当用户在Safari中浏览您的网站时,他们点击指向当前网页所在域中URL的通用链接,iOS会尊重该用户最有可能的意图,并在Safari中打开该链接。如果用户点击指向其他域中URL的通用链接,iOS将在您的应用中打开该链接。
对于运行9.0之前的iOS版本的用户,点击指向您网站的通用链接可在Safari中打开该链接。
app 如何支持Universal Links
你的web服务器(域名)需要支持
https
-
你app支持
Associated Domains
,操作看下图
-
Xcode工程里选择
Signing&Capabilities
,并且点击+ Capability
添加Associated Domians
.操作步骤如下
在
Associated Domians
里点击+
添加Domains
内容格式如下:
applinks:我的网站域名
。 比如百度的:applinks:www.baidu.com
创建
apple-app-site-association
文件,无后缀名!文件内容如下:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
注意
apps必须有,并且值为空数组。
details里列出自己网站想支持的app内容,值是数组
appID:的值格式如下:<开发者账号teamID.你app的bundleID>,teamID从步骤2的图片里可以看到。
paths:值是数组,里面的内容,是自己想支持的路径,可以使用通配符*
或者单个匹配字符?
- 把
apple-app-site-association
文件上传到web服务器根目录下。
比如你的网站是cn.bing.com
,就放在这个目录下即可。国内大部分是阿里云服务器,可以参考这个文章怎么把文件放到阿里云web服务器根目录下。
注意,也可以把
apple-app-site-association
文件上传到根目录的.well-known
目录下
上传完成之后:可以通过https链接直接访问不要有重定向。
https://
or/apple-app-site-association https://
/.well-known/apple-app-site-association
苹果也提供了网站验证apple-app-site-association
文件是否放置正确有效。
验证时,搜索框里输入的内容注意这个格式:
https://
,paths就是你在apple-app-site-association
文件里配置的路径
验证效果如下:
-
app delegate
里需要处理UserActivity
对象
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([Any]?) -> Void) -> Bool
{
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL,
let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
let path = components.path,
let params = components.queryItems else {
return false
}
print("path = \(path)")
if let albumName = params.first(where: { $0.name == "albumname" } )?.value,
let photoIndex = params.first(where: { $0.name == "index" })?.value {
print("album = \(albumName)")
print("photoIndex = \(photoIndex)")
return true
} else {
print("Either album name or photo index missing")
return false
}
}
8、配置参数
当你使用微信的sdk直接授权登录时,注册时一般都会加入Universal Links
,如下所示
[WXApi registerApp:APP_ID universalLink:UNIVERSAL_LINK];
但是如果你使用友盟中间转接做微信授权登录时,可能就会遇到坑了。我现在对接时,友盟和微信很早就支持了Universal Links
,但是友盟文档里没有明确标注出来,我最后在友盟sdk的版本迭代记录里查到了答案。通过友盟做微信第三方登录,需要在友盟里配置微信的Universal Links
,如下所示
//配置universal links相关参数//这里参数是[AnyHasable:Any],所以要rawValue代替
UMSocialGlobal.shareInstance()?.universalLinkDic = [
UMSocialPlatformType.wechatSession.rawValue:"https://xxxx/"
]
//友盟中,微信登录相关信息初始化
UMSocialGlobal.shareInstance()?.isUsingHttpsWhenShareContent = false // 当前网络请求是否用https
UMSocialManager.default()?.setPlaform(.wechatSession, appKey: whWeChatAppId, appSecret: whWeChatAppSerect, redirectURL: "https://www.umeng.com/social")//注册微信
这个值需要跟你在微信开放平台配置的Universal Links
保持一致,不然调起微信之后会提示Universal Links
不匹配。
敲黑板: 如果没有在友盟里配置微信的Universal Links
,就会报下面的错误:
2020-04-20 22:08:49 UMengShare<6.9.8>(Info):[UMSocialWechatHandler:978][SWI10008]微信授权登录提示该链接无法访问。
https://developer.umeng.com/docs/66632/detail/67043?um_channel=sdk
其实上面这个错误定位的是没有在微信开放平台开通微信登录权限,实际上我们在微信开放平台开通这个权限了。
在友盟里配置好微信的Universal links之后,调用微信登录就可以启动微信APP授权了
9、遇到的坑
- 手机里没有安装微信,启动网页登录授权时,点击取消APP crash 。这个是因为我的APP里使用了
SceneDelegate
,网页授权弹窗里有UIAlertView
,但是SceneDelegate
不支持UIAlertView
的回调。解决办法:在info.plist
里删除Application Scene Manifest
,工程里的SceneDelegate
文件是否删除都无所谓了。也要注释掉AppDelegate
里的scene有关的方法
/*这里删除设置info.plist里的 Application Scene Manifest,否则会影响微信登录授权取消崩溃,注释掉代码,iOS 13上的多场景功能就会被屏蔽掉。不用删除sceneDelegate.swift文件。后续如果支持多场景可以把注释拿掉就好了
// MARK: UISceneSession Lifecycle
@available(iOS 13.0,*)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
@available(iOS 13.0,*)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
*/