iOS应用间的跳转
如下所示:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let url = URL(string: "http://www.abc.com/query?name=zs&age=20")
UIApplication.shared.openURL(url!)
print(url?.scheme as Any)
print(url?.host as Any)
print(url?.path as Any)
print(url?.query as Any)
}
打印结果:
Optional("http")
Optional("www.abc.com")
Optional("/query")
Optional("name=zs&age=20")
可知 在一个 URL 对象中,http 即是
scheme
,www.abc.com 即是host
,/query 即是path
,name=zs&age=20即是query
其实有了 scheme 后就已经可以在应用间跳转了,例如 tel://
跳转去打电话 sms://
跳转去发短信,而 http://
就是跳转手机自带的浏览器 Safari,所以上面例子中的 url 改成http://,其实就已经可以通过UIApplication.shared.openURL(url!)
跳转过去了,只不过这时浏览器打开什么也没有
知道了上面之后,下面看应用间的跳转示例: 在 A 应用中有值
和体现
两个按钮,点击后跳转到B 应用并且分别到 B 应用中的充值
和体现
两个不同的页面。
- 1.首先需要知道跳往目标应用 B 的
scheme
,这里就定为hzc
如何设置scheme
呢?路径为:targets --- info --- URL Types
image.png
- 2.然后为了区分跳往 B 中后展示不同的页面(充值还是体现页面),这里可以在后面接上一个
host
,体现的就叫withdraw
,充值的叫recharge
,然后 A 中代码可以这样写:
A中:
// 点击体现
@IBAction func withdrawClick() {
let url = URL(string: "hzc://withdraw") // 可以通过
if UIApplication.shared.canOpenURL(url! ) {
UIApplication.shared.openURL(url!)
}else{
print("无法跳转")
}
}
// 点击充值
@IBAction func rechargeClick() {
let url = URL(string: "hzc://recharge")
if UIApplication.shared.canOpenURL(url! ) {
UIApplication.shared.openURL(url!)
}else{
print("无法跳转")
}
}
这时如果是 iOS9
之前,就已经可以跳转过去了,但是在 iOS9
之后,这样做了后还是跳转不了会报下面的错误
-canOpenURL: failed for URL: "hzc://recharge" - error: "This app is not allowed to query for scheme hzc"
这时我们还需要添加应用跳转的白名单,在info.plist
文件中添加一个数组类型LSApplicationQueriesSchemes
,然后把需要跳转的目标应用的 scheme
放进去:
之后就可以成功跳转到 B 应用了。但是这时候还不能区别跳转到 B 中的不同页面,下面我们继续,假设 B 应用结构如下:
image.png
然后在 AppDelegate 中:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
// 每次先执行一次popToRootViewController操作
let nav = UIApplication.shared.keyWindow?.rootViewController as! UINavigationController
nav.popToRootViewController(animated: false)
if url.host == "withdraw" {// 跳去提现页面
print("withdraw")
nav.viewControllers[0].performSegue(withIdentifier: "withdraw", sender: nil)
}else if url.host == "recharge"{// 跳去充值页面
print("recharge")
nav.viewControllers[0].performSegue(withIdentifier: "recharge", sender: nil)
}
return true
}
// 兼容 iOS9之前
func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
// 每次先执行一次popToRootViewController操作
let nav = UIApplication.shared.keyWindow?.rootViewController as! UINavigationController
nav.popToRootViewController(animated: false)
if url.host == "withdraw" {// 跳去提现页面
print("withdraw")
nav.viewControllers[0].performSegue(withIdentifier: "withdraw", sender: nil)
}else if url.host == "recharge"{// 跳去充值页面
print("recharge")
nav.viewControllers[0].performSegue(withIdentifier: "recharge", sender: nil)
}
return true
}
效果:
1.gif
2.gif
可见在 iOS9
之前左上角并没有返回A 应用的按钮,这是 iOS9
之后的功能,所以 iOS9
之前只能通过按home
键返回去。当然我们还可以在 B 应用中放一个按钮,点击返回 A 应用,原理和之前一样, 例如在 A 中设置 scheme
为 QC
,然后 B 中info.plist
文件中设置跳转白名单,将QC
加入白名单里面。然后在 B 中实现按钮点击回到 A 中即可。
拓展:
类似一些第三方 SDK 如 QQ、微信,不同的应用都可以往 QQ 或者微信跳,那么当从微信或 QQ 完成业务后回跳到与其对接的App 的时候, 微信或者 QQ 必须就要知道这些与其对接的 App的 scheme
,所以这时候一般情况下这些第三方 SDK 中都会说明怎么设置这个 scheme,一般都是前缀 + AppKey
,这个AppKey
就是我们在注册第三方平台时生成的AppKey
,例如微信的 wx123456...
,微博的 wb123456...
。