swift 学习。 URL类

588 阅读11分钟

/*

     NSURL 再swfit 里面被替换为 URL 。 尽量使用URL 类

     URL 由字符串构造得到。而URL 分为 本地路径和网络url字符串两种字符串。

     本地路径字符串URL。/var/mobile/Containers/Data/Application/3AC8C51B-5C74-43CF-90D7-2F88F0215486/Documents/mySoundsImage/

     本地路径字符串形如 file:///var/mobile/Containers/Data/Application/3AC8C51B-5C74-43CF-90D7-2F88F0215486/Documents/mySoundsImage/

     本地URL 一般是这两种格式的字符串构造的 。

     ///第一种不带file:/// 格式的 是我们利用

     let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

     let firstDocumentPath = documentPath.first ?? ""

     获取documentPath路径的。自己拼接Url的。 只要是通过NSSearchPathForDirectoriesInDomains获取的路径就不带有file:///的路径。

     特殊:: 通过URL(string: firstDocumentPath) 创建 的 url 得到的URL 确实是没有file:///的路径的。

            但是通过URL(fileURLWithPath: firstDocumentPath) 出来的就URL 就会是带有file:///的路径的

     

     第二种方式获取 本地URL

     let fileManager = FileManager.default

     guard let documentsDirectoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }

     这个documentsDirectoryURL 就是的字符串就是带有file:///的路径。

     file:///var/mobile/Containers/Data/Application/9C57BAD3-6E69-44B4-9AA6-D38CBEB032E9/Documents/mySoundsImage/

     这个样子的。

     /// 获取本地沙盒路径的两种API 后面介绍。

     

     /// 网络URL

     网络url 一般是这个结构的 "api.jaco.live/reel/1/reel…" 这种的。

     

     介绍下 这两种URL字符串的组成部分

     网络URL

     "api.jaco.live/reel/1/reel…"

     1.协议(Scheme): 开头的://之前的  https http ftp.

     2.主机(Host):域名或者IP地址。api.jaco.live /192.168.1。

     3.端口号(Port): ":8080" ":443" 字符串。如果url没有 使用默认的。

     4.路径(Path)资源在服务器位置以"/"开始的一层层路径。文件夹。

     5.请求参数。查询参数(Query) 以?开始,接在Path后面。key=value&key=value 。用=连接key和Value。用&连接两个参数。

     6.片段标识符(Fragment): 片段标识符用于指定资源中的特定部分。片段标识符以井号 # 开始。

     

     //对应API 获取以上6个内容为

     let url  = URL(string: "api.jaco.live/reel/1/reel…")

     1.获取scheme url.scheme.得到https  取得是 :之前的内容,如果没有:scheme返回nil

     2.获取Host url.host 得到api.jaco.live 很直接的查找方式就直接找“://”它后面的+"/"之间的部分如果没有就返回nil

     3.获取port url.port 得到8080 是一个Int 类型。 没有":"了 。如果构造的url没有明确标明:8080 那么得到的是nil

     5.获取路径 /reel/1/reel/material/c/query 带着开始的"/"斜杠。获取规则是截取Host后面的,如果host没有 规则没试出来,会导致返回"" 或者nil 。

     6.获取Query abc=12&dd=15  不带问号。 问号后面的

     //其他url获取部分内容API。 后续介绍完毕API 再介绍。

     ///如果是本地的url 那么这6部分分别是什么?

     

     let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

     let firstDocumentPath = documentPath.first ?? ""

     let url = URL(string:firstDocumentPath)

    

     

     /// url.host、url.port、url?.query三个一定是nil 不管是带不带file:/// 格式的URL

     /// scheme . 如果得到的URL是带有file:///的就返回file。不是就返回nil。所以这里就可以得到结论。如果是通过URL(string:"")构造的就会返回nil 了。如果是通过另外两种方式就会返回file。

     /// path. 本地地址url 的path 。不管url是带file:/// 还是不带file:/// 的 。都会返回 不带file:///其余全部字符串。这个在我们只有URL的时候也许会有用。但是 其实本地url 带不带file:/// 俩API都可以正常使用。

     本地URL 的时候很有用。因为不同的URL构造方法。其字符串不同,有可能是 /var/mobile... 还有可能是file:///var/mobile... 还有可能是 ///var/mobile 形式的字符串。

     如果是本地字符串 想要通过URL获取字符串 就是用path 获取。所以以上几个属性。本地字符串就记住 path 就可以。

     

      介绍完毕URL基本概念,介绍URL类基础使用

     1. public init?(string: String)

     2. public init?(string: String, relativeTo url: URL?)

     ///根据字符串初始化URL 方法。 该方法 传入的字符串如果是空字符串 返回nil,如果是非法字符串也返回nil。

     /// 那什么是非法字符串呢。 比如表情。空格,特殊字符,中文等非ASSIH码。但是swift5.X版本做了优化,有的时候有空格啊 中文啊 表情啊,都会被自动编码创建出来URL。并不为nil

     ///  let urlStr = "https:// 哈哈/ path with spaces" 这个会返回nil是因为“ 哈哈”。后面的“/ path with spaces” 他并不会导致返回nil。总之就是不同版本可能效果不同。特殊字符,非ASSIH码的字符有可能返回nil。

     /// 本地路径同理。 有中文和空格表情字符什么的 也有可能返回空。

     /// 总结就是如果使用 以上俩API 初始化URL 。确保字符串格式正确。无特殊字符,表情,中文等特殊情况都会成功初始化出url,不保准。

     

     //relativeTo 。 相对的。 俩参数 一个 字符串 一个URL。

     API 概念为。 如果 字符串 string 是一个绝对的url 就是 带有http:// 的 或者是file:/// 的 或者不是带有file:/// 的本地url 。不是相对url字符串的(就不是path的/w/d/w这种的)这种情况下。后面的relativeTo: baseURL 没什么用了。直接用string 初始化url。

     如果relativeTo 是一个相对路径“abc/def”这种的。abc前面不需要/ 会自动拼上去

     总结就是 如果是本地路径。那么relativeTo 是一个相对路径。 不要携带"/"前缀空格。baseUrl也不需要携带最后面的/ 。

     如果 relativePath 是一个以斜杠开头的绝对路径,它将被视为完整路径,不再受到基础 URL 的影响。

     

     如果是网络URL 。 也是 正常使用。相对路径 是不带/开始的字符串。relativeTo是BaseUrl。

     

     3. public init(fileURLWithPath path: String, isDirectory: Bool, relativeTo base: URL?)

     4. public init(fileURLWithPath path: String, relativeTo base: URL?)

     5. public init(fileURLWithPath path: String, isDirectory: Bool)

     6. public init(fileURLWithPath path: String)

     该API是初始化本地路径URL的方法。这个方法构造出来的URL之后,再从这个URL转出来字符串就带上了 file:/// 前缀或者是 /// 三个斜杠前缀。

     

     path 本地路径的绝对路径。可以使文件夹 也可以是文件。 isDirectory path是否是文件夹。如果可以确定是文件夹 最好传True。优化性能。 relativeTo base  同理的 baseUrL 兼容拼接的。想要拼接 path 就变成了相对路径。跟上面一样,要是绝对路径 baseUrl就被忽略了。就是path 不能带前缀/。

     7. absoluteString 返回URL的绝对路径。绝对字符串。

     针对本地路径URL。我们之前提过 通过不同方式构造URL对象 ,其内部包含的字符串可能有三种情况。其·1.是我们通过documentDirectory获取的地址字符串。然后通过public init?(string: String)构造的字符串。 其内部存的就是/var/mobile... 此时获取的就是/var/mobile...。 其·2.通过URL(fileURLWithPath: mySoundPath) 初始化的URL。其内部存的字符串是 file:///var/moblie... 这种格式的。再通过absoluteString返回的时候就是file:///var/moblie...这种格式的。其·3.还有一种情况是 public init?(string: String, relativeTo url: URL?) 这种的 有baseUrl关联的 如果baseUrl是var/moblie... 的。构造之后得到的URL内部存的情况更复杂 ,通过absoluteString获取的是///var/mobile... 样子的。获取字符的时候就返回///var/mobile...。但是以上三种字符串 都可以正常使用初始化出来URL。

     针对网络URL。就是直接获取整个字符串所有内容。这个字符串没有什么前缀的区分。

     8.relativeString 相对路径。 如果baseUrl为nil 和absoluteString一样,如果baseUrl不为空,返回relativeString。可以把通过 baseUrl和.relativeString一起初始化出来URL的分割出来。

     注意 通过 后面appendingPathComponent方法添加的path 不能分割出来。只是通过构造器创建时候能区分出来。

     并且如果显示通过baseUrl构造出来的URL 然后再利用appendingPathComponent方法拼接一个path。然后再利用relativeString获取 也是可以获取到的。获取的内容是拼接之后的。

     9. baseURL 。同理 初始化的时候有baseUrl就返回 灭有就返回 nil。

     10. absoluteURL 。如果原url是绝对路径的URL 就返回一个相同的,深拷贝的uRL,如果原URL是一个相对URL 有baseUrl的 会返回一个新的URL,这个新URL的路径就是绝对URL的路径。

     

     11. isFileURL 是否是本地路径。 内部逻辑就是判断URL内部是否是file:///格式的。这样的功能就很局限,本地路径URL有很多表示形式。比如通过URL(string:)创建的还有通过相对URL 创建的。就是上面介绍三类方法构造URL。只有构造出来是带有file:///格式的才会是true。 通过相对URL创建的URL(string: relativePath, relativeTo: baseUrl2)取决于baseUrl 是否是携带有file:/// 格式的。所以通过它判断 只能是是判断通过 URL(fileURLWithPath: mySoundPath)构造的字符串是True。

     另外 随便初始化一个url 他也不是本地路径 他也不是网络URL 只要他有file:/// 就会返回Ture 没有就返回False .

     12. public var user: String? { get }

     13. public var password: String? { get }

     用户名和密码。 有些网络的URL 是可以把账号密码拼接在URL上的。比如我么常用的git。

     "username:password@example.com/path/to/res…"

     

     14.  public var relativePath: String { get }

     相对URL 的部分。 如果初始化是通过相对URL初始化的。那么这个relativePath获取的就是相对部分。就是URL(string: "path/ddd", relativeTo: baseUrl4)的string 部分。 不区分网络还是本地路径URL。

         如果初始化同通过绝对路径初始化的URL。如果是本地URL 那么这个属性就是获取的和absoluteString一样。远程的是path。

     总结 这个属性 也是条件逻辑。

     15   public var fragment: String? { get } 获取的是字符串最后的#后面的内容

     16. public var hasDirectoryPath: Bool { get }

     用于判断 URL 对象是否表示一个目录的路径。如果 URL 是本地文件系统的目录路径,hasDirectoryPath 将返回 true;否则,返回 false。

     

     17.pathComponents . 获取URL 的路径.获取的数组。

     如果是本地路径, 就全部分割。第一个元素是/ 然后就是文件路径。

     如果是远程URL 。 就从域名之后 path 不分开始 切割为数字。不包括?后面的qury

     18.lastPathComponent 最后一个文件夹的名字 如果是远程的就是?之前的那个名字或者是文件名字

     19 .appendingPathComponent url添加一个path

     本地的地址 就在最后面添加路径。 在线url 就在?之前的path添加

     20 . appendPathComponent 和19 一样 区别是 一个返回url 一个再原有url上改。

     20  public func deletingLastPathComponent() -> URL 删除最后的path的url

     

     21.   public mutating func deleteLastPathComponent() 同20 删除最后一个path 在原有url上改写。

     22.  public func appendingPathExtension(_ pathExtension: String) -> URL

     23.  public mutating func appendPathExtension(_ pathExtension: String)

     为一个URL路径添加拓展名,得到一个新的URL 就是再path最后的变成path.txt。变成文件名了。如果是在线url 有?query的 拼的也是最后path

     

     

     /// URL编码

     是指先对url字符串进行编码 ,然后再初始化构造URL

     public func addingPercentEncoding(withAllowedCharacters allowedCharacters: CharacterSet) -> String?

     对字符串先进行编码。 默认是UTF-8编码。CharacterSet编码字符集 内置一些字符集。可以理解为一个数组 包含着很多字符。

     CharacterSet.controlCharacters // 换行符 制表符 /n /t /r 等控制符。进行编码

     whitespaces // 空字符

     newlines/// 换行符 包括 /r /n 回车符

     whitespacesAndNewlines//空字符+换行符

     decimalDigits /// 阿拉伯数数字0-9

     letters/// 字母字符 A-Z a-z 包括大小字母集合。

     lowercaseLetters ///小写字母

     uppercaseLetters/// 大写字母

     alphanumerics /// 数字和字母一起的结合

     decomposables

     nonBaseCharacters

     illegalCharacters

     punctuationCharacters

     capitalizedLetters

     urlUserAllowed

     urlPasswordAllowed ///编码用户信息和密码部分

     urlHostAllowed /// urlHost 域名部分编码

     urlPathAllowed /// path 部分编码

     urlQueryAllowed /// ? 后面部分编码

     urlFragmentAllowed /// #后面的编码

     /// 字符集三种方式

     1. 编码使用

     2.判断是否有字符集内容存在

    let range = inputString.rangeOfCharacter(from: .alphanumerics)

     range 是第一个符合字符集的range

     3. let ddd = inputString.components(separatedBy: decimalDigits).joined()

     取出 非字符集内容的字符串

     4.let numbersOnly = inputString.unicodeScalars.compactMap { decimalDigits.contains(0)?Int(String(0) ? Int(String(0)) : nil }

     取出符合字符集的字符串。

     

     /// 获取doument的URL

    方式1 if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

         let documentPath = documentsDirectory.path

         print("Document目录路径:(documentPath)")

     }

     

    方式2 let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

     let firstDocumentPath = documentPath.first ?? ""

     

     */