「Swift」跳转至第三方App|淘宝、天猫、京东、大众点评

1,608 阅读5分钟

前言:如何从自己的App跳转到相应的淘宝、天猫、京东等第三方App中相应的商品或店铺

1.配置环境

需要在Info.plist 里面建立一个叫 LSApplicationQueriesSchemes 的 Array类型,将相应的app Scheme添加进LSApplicationQueriesSchemes字段

该字段并不是所谓的白名单,而是在iOS9后,如果想要使用canOpenURL方法检查是否可以打这个URL或可以处理该URL的的App
需要在info.plist里添LSApplicationQueriesSchemes字段来预设url,否则是否安装都会返回NO。如果想要打开其他App,直接使用openURL即可
在这里插入图片描述
常见的第三方App Scheme

<key>LSApplicationQueriesSchemes</key>
 <array>
    <!-- 微信 URL Scheme 白名单-->
    <string>wechat</string>
    <string>weixin</string>

    <!-- 新浪微博 URL Scheme 白名单-->
    <string>sinaweibohd</string>
    <string>sinaweibo</string>
    <string>sinaweibosso</string>
    <string>weibosdk</string>
    <string>weibosdk2.5</string>

    <!-- 京东 URL Scheme 白名单-->
    <string>openapp.jdmobile</string>

	<!-- 淘宝 URL Scheme 白名单-->
    <string>taobao</string>

	<!-- 天猫 URL Scheme 白名单-->
    <string>tmall</string>

    <!-- 支付宝  URL Scheme 白名单-->
    <string>alipay</string>
    <string>alipayshare</string>
</array>

2.编写跳转方法

ps:以下方法参数均是使用pc端网页url,即可跳转至相对应App的页面

1.跳转至淘宝店铺

传入的url必须带有shopId参数,如:shop561496733.taobao.com/?spm=a230r.…

///跳转至淘宝店铺页
    public func turnToTaobaoShop(urlStr: String) {
         let url = URL(string: urlStr)!
         let host = url.host!
         let startIndex = host.index(host.startIndex, offsetBy: 4)
         let endIndex = host.firstIndex(of: ".") ?? host.endIndex
         if endIndex == host.endIndex { return }
         let shopId = host[startIndex..<endIndex]
         
         guard let appURL = URL(string: "taobao://shop.m.taobao.com/shop/shop_index.htm?shop_id="+shopId+"") else {
             return
         }
        
        /// 判断手机是否安装了淘宝App
         if UIApplication.shared.canOpenURL(appURL) {
             UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
             
         } else {
         /// 没安装淘宝,使用浏览器打开相对应页面
             UIApplication.shared.open(url, options: [:], completionHandler: nil)
         }
     }
2.跳转至淘宝商品

传入的url必须带有商品id,与店铺Id类似,不再举例

///跳转至淘宝商品详情页
    public func turnToTaobaoItem(urlStr: String) {
        let url = URL(string: urlStr)!
        let itemDict:[String:String] = url.urlParameters ?? [:]
        let itemId = itemDict["id"]!
        
        guard let appURL = URL(string: "taobao://item.taobao.com/item.htm?id="+itemId+"") else {
            return
        }
        
         /// 判断手机是否安装了淘宝App
        if UIApplication.shared.canOpenURL(appURL) {
            UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
            
        } else {
        /// 手机没有安装App,使用浏览器打开相对应页面
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
    }
3.跳转至天猫店铺

因为天猫店铺的url中不带店铺Id,所以需要通过在店铺页面上打开网页检查器,取出店铺Id并与url一起传入参数

///跳转至天猫店铺页
    public func turnToTmallShop(urlStr: String, shopId: String) {
        guard let url = URL(string: "tmall://page.tm/shop?shopId="+shopId+"") else {
            return
        }
        
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            
        } else {
            UIApplication.shared.open(URL(string: urlStr)!, options: [:], completionHandler: nil)
        }
    }
4.跳转至天猫商品
///跳转至天猫商品详情页
    public func turnToTmallItem(urlStr: String) {
        let url = URL(string: urlStr)!
        let itemDict:[String:String] = url.urlParameters ?? [:]
        let itemId = itemDict["id"]!
        
        guard let appURL = URL(string: "tmall://tmallclient/?action:item:id="+itemId+"") else {
            return
        }
        
        if UIApplication.shared.canOpenURL(appURL) {
            UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
            
        } else {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
    }
5.跳转至京东商品详情或商品店铺
///跳转至京东商品详情页或店铺页
    func TurnToJD(urlStr: String){
        let jdDict = ["category":"jump", "des":"getCoupon", "url":urlStr]
        guard let jdStr = jdDict.formatJSON() else { return }
        let url = "openApp.jdmobile://virtual?params=\(jdStr)"
        let utf8Str = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        
        guard let appURL = URL(string: utf8Str ?? "") else {
            return
        }
        
        if UIApplication.shared.canOpenURL(appURL) {
            UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
            
        } else {
            UIApplication.shared.open(URL(string: urlStr)!, options: [:], completionHandler: nil)
        }
    }

6.添加扩展方法
因为以上方法使用到了url参数分解和序列化字典到JSON字符串,所以需要添加一下扩展方法

// MARK: - Extension
extension URL {
    var urlParameters: [String: String]? {
        guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
        let queryItems = components.queryItems else { return nil }
        return queryItems.reduce(into: [String: String]()) { (result, item) in
            result[item.name] = item.value
        }
    }
}

extension Dictionary {
    /// 将JSON字符串反序列化到字典中
    public static func constructFromJSON (json: String) -> Dictionary? {
        if let data = (try? JSONSerialization.jsonObject(
            with: json.data(using: String.Encoding.utf8,
                            allowLossyConversion: true)!,
            options: JSONSerialization.ReadingOptions.mutableContainers)) as? Dictionary {
            return data
            
        } else {
            return nil
        }
    }
 
    /// 序列化字典到JSON字符串
    public func formatJSON() -> String? {
        if let jsonData = try? JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions()) {
            let jsonStr = String(data: jsonData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
            return String(jsonStr ?? "")
        }
        
        return nil
    }
}

注:给大家排除一个网上大多数文章所传输的误解
网上大多数跳转至第三方App的文章都要求大家配置URL types,其实这个配置文件不是用来跳转至外部App,而是用来从外部App跳转至自己的App中使用的,如自己设置了一个URL Scheme,举个🌰:设置了URL Schemes:textAppScheme,则可以在浏览器通过textAppScheme://,这个网址来跳转至手机上自己的App中,所以这个并不是作为跳转至其他第三方App的必要步骤!!!
在这里插入图片描述

整理不易,如有帮助,请多多点赞收藏!谢谢大家!

2023年11月24日更新修订跳转至淘宝商铺方法:

由于淘宝商铺的URL格式进行了变化,在URL中不会再展示shopId内容,当前淘宝店铺URL格式:whitepure.taobao.com/?spm=2013.1…

所以将跳转至淘宝商铺的方法更改于跳转至天猫商铺相似,需要使用网页检查器,获取店铺的shopId,并于url一起传入至方法参数。

///跳转至淘宝店铺页
    public func turnToTaobaoShop(urlStr: String, shopId: String) {
        guard let url = URL(string: "taobao://shop.m.taobao.com/shop/shop_index.htm?shop_id="+shopId+"") else {
            return
         }
        
         if UIApplication.shared.canOpenURL(url) {
             UIApplication.shared.open(url, options: [:], completionHandler: nil)
             
         } else {
             UIApplication.shared.open(URL(string: urlStr)!, options: [:], completionHandler: nil)
         }
     }

如再次出现因URL格式修改而无法跳转的方法,后续将继续完善相关跳转方法
收藏该文章,以防后续迷路!


2023年12月5日更新环境配置细节和新增大众点评店铺页面跳转方法:

1.更新环境配置细节:

今天进行新增方法时发现,在Info.plist文件中,原先的LSApplicationQueriesSchemes字段名已经不见了,如今已经变成了Queried URL Schemes,但是在Source codeKey值仍为LSApplicationQueriesSchemes

info.plist文件中: image.png

Source Code中:

image.png

再次解释一下,如果在info.plist文件中未添加这个URL Scheme则会在跳转的时候出现ERROR: error:"This app is not allowed to query for scheme dianping" 解决办法是在info.plist文件内添加对应的配置项,将其列为白名单才可以正常检查是否已经安装此程序。

2.新增大众点评店铺页跳转方法:

传入的url必须带有shopId参数,如:m.dianping.com/tuan/deal/8… 所以该链接需要从大众点评 App的商品详情页分享-复制链接进行获取

///跳转至大众点评店铺页
public func turnToDianPingShop(urlStr: String) {
    let url = URL(string: urlStr)!
    let itemDict:[String: String] = url.urlParameters ?? [:]
    let shopId = itemDict["shopId"]!
    
    guard let appURL = URL(string: "dianping://shopinfo?shopid="+shopId) else {
        return
    }

    if UIApplication.shared.canOpenURL(appURL) {
        UIApplication.shared.open(appURL, options: [:], completionHandler: nil)

    } else {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}

由于当前大众点评只能跳转至店铺页,所以当安装了大众点评App时,会直接跳转至店铺页;当没有安装大众点评App时,会在浏览器中打开商品详情页。

后续会持续进行更新
收藏该文章,以防后续迷路!