iOS应用间的跳转

如下所示:

override func touchesBegan(_ touches: Set, 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!)跳转过去了,只不过这时浏览器打开什么也没有

iOS应用间的跳转_第1张图片
image.png

知道了上面之后,下面看应用间的跳转示例: 在 A 应用中有体现两个按钮,点击后跳转到B 应用并且分别到 B 应用中的充值体现两个不同的页面。

  • 1.首先需要知道跳往目标应用 B 的 scheme,这里就定为 hzc
    如何设置 scheme 呢?路径为:targets --- info --- URL Types
    iOS应用间的跳转_第2张图片
    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 放进去:

image.png

之后就可以成功跳转到 B 应用了。但是这时候还不能区别跳转到 B 中的不同页面,下面我们继续,假设 B 应用结构如下:


iOS应用间的跳转_第3张图片
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
    }

效果:


iOS应用间的跳转_第4张图片
1.gif

iOS应用间的跳转_第5张图片
2.gif

可见在 iOS9之前左上角并没有返回A 应用的按钮,这是 iOS9之后的功能,所以 iOS9之前只能通过按home键返回去。当然我们还可以在 B 应用中放一个按钮,点击返回 A 应用,原理和之前一样, 例如在 A 中设置 schemeQC,然后 B 中info.plist 文件中设置跳转白名单,将QC 加入白名单里面。然后在 B 中实现按钮点击回到 A 中即可。

拓展:
类似一些第三方 SDK 如 QQ、微信,不同的应用都可以往 QQ 或者微信跳,那么当从微信或 QQ 完成业务后回跳到与其对接的App 的时候, 微信或者 QQ 必须就要知道这些与其对接的 App的 scheme,所以这时候一般情况下这些第三方 SDK 中都会说明怎么设置这个 scheme,一般都是前缀 + AppKey ,这个AppKey就是我们在注册第三方平台时生成的AppKey,例如微信的 wx123456...,微博的 wb123456...

你可能感兴趣的:(iOS应用间的跳转)