相关文章推荐
神勇威武的滑板  ·  ExcelVBA 宏 ...·  4 月前    · 
飘逸的哑铃  ·  AWS3文件上传 golang ...·  5 月前    · 
  • protocol/scheme: 传输协议,比如http、https等

  • credentials(可选): 一些http服务器支持通过url来校验用户信息,当然这是一种不普遍也不安全的方式

  • hostName: 资源服务器的主机地址

  • port(可选): 端口号,指定客户端应该连接哪个端口,如果忽略则使用默认端口。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL中就不能省略端口号这一项

  • path: 绝对路径,由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。

  • query(可选): 查询,url最后部分是查询字符串。这个值是从path用?隔开的。多个参数每个参数用&分隔。查询字符串不能包含回车空格换行字符

  • fragment: 信息片断,字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释

  • URL的拆分

    我们已经知道一个URL的基本结构,那么在iOS中我们如何获取对应结构的元素呢,答案是利用系统的 URLComponents 类进行处理

    我们简单看下这个类的内部结构

    几个初始化方法

    public init?(url: URL, resolvingAgainstBaseURL resolve: Bool)
    public init?(url: URL, resolvingAgainstBaseURL resolve: Bool)....

    public var scheme: String?
    public var user: String?
    public var password: String?
    public var host: String?
    public var port: Int?
    public var path: String
    public var query: String?
    public var fragment: String?
    public var queryItems: [URLQueryItem]?

    我们可以看到URL的每个结构在URLComponents中都有对应的属性

    举个栗子:

         guard let urlComponents = URLComponents.init(string: "http://mobile.hktsc.cc/services/list?appPage=serviceList&brandId=1") else {
            return
        if let scheme = urlComponents.scheme {
            print("scheme: \(scheme)")
        if let user = urlComponents.user {
            print("user: \(user)")
        if let password = urlComponents.password {
            print("password: \(password)")
        if let host = urlComponents.host {
            print("host: \(host)")
        if let port = urlComponents.port {
            print("port: \(port)")
        print("path: \(urlComponents.path)")
        if let query = urlComponents.query {
            print("query: \(query)")
        if let queryItems = urlComponents.queryItems {
            print("queryItems: \(queryItems)")
            for (index, queryItem) in queryItems.enumerated() {
                print("第\(index)个queryItem name:\(queryItem.name)")
                if let value = queryItem.value {
                    print("第\(index)个queryItem value:\(value)")
    

    scheme: http
    host: mobile.hktsc.cc
    path: /services/list
    query: appPage=serviceList&brandId=1
    queryItems: [appPage=serviceList, brandId=1]
    第0个queryItem name:appPage
    第0个queryItem value:serviceList
    第1个queryItem name:brandId
    第1个queryItem value:1

    常用的使用场景是URL参数的截取,或者根据url的不同进行一些不同的操作,比如跳转等等

    2. openURL

    openURL主要有下面几个主要的应用

    应用间的跳转:

    在iOS中我们可以通过URL Schemes + openURL方法实现应用间的跳转,下面先讲几个概念和方法

    URL Schemes:我们在工程中配置的 URL Schemes可以理解为我们App在手机上的一个地址(类比网络中的URL,比如http://www.baidu.com,他的schemes是http),其他的已安装的应用可以通过这个地址找到我们的App,实现跳转。当然这个URL Schemes可以有多个

    如图,使我们经常会添加的几个URL Schemes,目的是为了第三方应用能够跳转回我们的App。

    iOS9之后,新增了 URL Schemes白名单的概念,这个稍后具体再讲

    openURL: 我们可以通过这个方法打开一个URL,假如我们这个URL的schemes和我们已安装的某个app的URL Schemes一样的话,我们就可以打开这个app。

    比如你可以使用下面的方法直接跳转到微信

    UIApplication.shared.openURL(URL(string: "weixin://")!)// iOS10之前
    UIApplication.shared.open(URL(string: "weixin://")!, options: [:], completionHandler: nil) // iOS10
    

    再或者我们常用的拨打电话

    UIApplication.shared.openURL(URL(string: "tel://10086")!)
    

    一般,我们在跳转之前都需要判断下能不能够打开这个url(能够打开则跳转,不能则提示或者隐藏什么的),系统为我们提供了canOpenURL这个方法来判断我们是否能够打开某个url.但是在iOS9之后,我们需要在info.plist中配置URL Schemes 白名单,只有添加了白名单,我们的这个方法才能生效。否则会提示"This app is not allowed to query for scheme",如下图

    来看下官方提供的url格式

     iosamap://navi?sourceApplication=applicationName&backScheme=applicationScheme&poiname=fangheng&poiid=BGVIS&lat=36.547901&lon=104.258354&dev=1&style=2
    
  • iosamap:高德地图的官方url scheme,确保能跳到高德地图
  • navi: url中的host,这边表示服务类型为导航
  • sourceApplication,backScheme及后面的:这部分为url中query,我们需要传递的具体的参数
  • 通过这个url我们可以直接从我们App跳到高德地图导航页面进行导航,当然前提是我们已经安装了高德地图,可以使用canOpenUrl来判断,具体的可参考高德官方的文档

    那么高德内部是如何接收我们的参数的呢?,来看这两个熟悉的回调方法

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool 
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool 
    

    以上两个方法是系统提供给我们的openUrl回调方法,比如我们跳转到高德地图后,他那边就会执行这个方法,有一点需要注意的是第二个方法是在iOS9才出现的方法,也就是说如果你的系统是iOS9及之后的话他只会走第二个方法,iOS9之前才会走第一个方法。我们可以在这里获取相应的url并进行处理。我们平时会在这边处理友盟分享和支付相关的一些回调

    3. 本地文件的访问

    url也可以用来访问我们本地的资源文件,其实和网络中的url一样,只不过资源服务器变成了我们本机,少去了资源传递的过程,最直接的资源定位符,这一块就先不做详细叙述了