Swift中的URL

所属分类:ios | 发布于 2024-02-13

URL在外面构建的应用程序中无处不在,通常URL有两类。

1、本地文件URL,我们使用URL绑定路径引用本地文件。

2、远程URL,使用URL从指定的API的路径获取数据,或获取图像并显示。

URL基本操作

将字符串值转化为URL

let url = URL(string: "https://www.google.com")!

这种初始化方法的缺点是,生成的URL是一个可选值,在使用的时候需要强制解包。创建一个简单的扩展,通过使用自定义初始值来帮我们实现自动解包。

extension URL {
    init(_ string: StaticString) {
        self.init(string: "\(string)")!
    }
}

var unwrappedURL = URL("https://www.google.com")

URL转String

可以使用URL的absoluteString属性把URL转换成String

print(unwrappedURL.absoluteString) // Prints: https://www.google.com

使用相对URL

在Swift中构建API时经常使用的一种场景是通过使用基本URL来构建连接。

例如,我们可以构建一个博客文章类别页面,如下

let category = "ios"
let baseURL = URL(string: "https://wenge365.com")!
let blogURL = URL(string: category, relativeTo: baseURL)!
print(blogURL) // Prints: swift -- https://wenge365.com
print(blogURL.absoluteString) // Prints: https://wenge365.com/ios

同时,如果URL本身是相对的,我们可以获得某个链接的基础URL

let absoluteURL = URL(string: "https://wenge365.com")!
let relativeURL = URL(string: "ios", relativeTo: baseURL)!
print(absoluteURL.baseURL) // Prints: nil
print(relativeURL.baseURL!) // Prints: https://wenge365.com

打印host和scheme

let swiftLeeURL = URL(string: "https://wenge365.com")!
print(absoluteURL.host!) // Prints: wenge365.com
print(absoluteURL.scheme!) // Prints: https

URL Components组件

链接基本上是由几个组件组成的。我们之前已经在印刷声明中看到了一些内容,但还有更多的内容需要涵盖:

let twitterAvatarURL = URL(string: "https://twitter.com/twannl/photo.png?width=200&height=200")!
print(twitterAvatarURL.path) // Prints: /twannl/photo.png
print(twitterAvatarURL.pathComponents) // Prints: ["/", "twannl", "photo.png"]
print(twitterAvatarURL.pathExtension) // Prints: png
print(twitterAvatarURL.lastPathComponent) // Prints: photo.png

获取查询参数

上面的twitter链接中有width和height两个参数,我们需要获取这两个参数以便于按正确的比例显示头像。

可以使用URLComponents来初始化链接。它返回一个新的属性集合,可以将其视为一个URL解析器,它让我们能访问参数项:

let components = URLComponents(string: "https://twitter.com/twannl/photo.png?width=200&height=200")!
print(components.query!) // width=200&height=200
print(components.queryItems!) // [width=200, height=200]

我们可以通过遍历查询项数组来直接访问值:

let width = components.queryItems!.first(where: { queryItem -> Bool in
    queryItem.name == "width"
})!.value!
let height = components.queryItems!.first(where: { queryItem -> Bool in
    queryItem.name == "height"
})!.value!
let imageSize = CGSize(width: Int(width)!, height: Int(height)!)
print(imageSize) // Prints: (200.0, 200.0)

但是,上面的代码使用了大量的unwrap,显得臃肿,代码可读性不高。因此我们可以使用自定义下标扩展,使代码看起来更好

extension Collection where Element == URLQueryItem {
    subscript(_ name: String) -> String? {
        first(where: { $0.name == name })?.value
    }
}
let imageWidth = Int(components.queryItems!["width"]!)!
let imageHeight = Int(components.queryItems!["height"]!)!
let size = CGSize(width: imageWidth, height: imageHeight)

 

构建一个带参数的URL

有一个需求时从字典中构建一个带请求参数的URL,例如:

let parameters = [
    "width": 500,
    "height": 500
]
var avatarURLComponents = URLComponents(string: "https://twitter.com/twannl/photo.png")!
avatarURLComponents.queryItems = parameters.map({ (key, value) -> URLQueryItem in
    URLQueryItem(name: key, value: String(value))
})
print(avatarURLComponents.url!) // Prints: https://twitter.com/twannl/photo.png?width=500&height=500

编写一个扩展,该扩展更容易地讲字典转换为查询项数组:

extension Array where Element == URLQueryItem {
    init<T: LosslessStringConvertible>(_ dictionary: [String: T]) {
        self = dictionary.map({ (key, value) -> Element in
            URLQueryItem(name: key, value: String(value))
        })
    }
}
let pagingParameters = [
    "offset": 2,
    "limit": 50
]
var twitterFeedURLComponents = URLComponents(string: "https://twitter.com/feed")!
twitterFeedURLComponents.queryItems = .init(pagingParameters)
print(twitterFeedURLComponents.url!) // Prints: https://twitter.com/feed?offset=2&limit=50

文件URL

使用isFileURL属性可以区分远程URL和本地URL

var remoteFileURL = URL(string: "https://www.twitter.com/avatar.jpg")!
var fileURL = URL(string: "file:///users/antoine/avatar.jpg")!
print(remoteFileURL.isFileURL) // Prints: false
print(fileURL.isFileURL) // Prints: true

isFileURL属性只有在URL scheme为file:时才返回true。

获取本地文件URL扩展

print(fileURL.pathExtension) // Prints: jpg

获取本地文件的文件名(不包含扩展)

要从文件URL中获取文件名,我们可以使用lastPathComponent并通过删除文件扩展名来提取文件名:

print(fileURL.deletingPathExtension().lastPathComponent) // Prints: avatar

 

2025年4月15日更新

1、创建URL的方式

1.1、从字符串创建URL,Creating a URL from a string

该方法对应的创建的远程URL。

1.2、从字符串路径创建文件URL,Creating a file URL from a  string path

该方法对应创建的本地文件URL。

1.3、还有其它好几种方式,详情见官方文档

2、访问URL的各个部分

2.1、func fragment(percentEncoded: Bool) -> String?

2.2、func host(percentEncoded: Bool) -> String?

2.3、func path(percentEncoded: Bool) -> String

2.4、var lastPathComponent: String

2.5、var pathComponents: [String]

2.6、var pathExtension: String

2.7、func path(percentEncoded: Bool) -> String

2.8、var scheme: String?

2.9、var port Int?

3、访问URL的标识

3.1、var baseURL: URL?

3.2、var absoluteString: String

3.3、var absoluteURL: URL

3.4、var relativePath: String

3.5、var relativeString: URL

3.6、standardized: URL

3.7、standardizedFileURL: URL

4、访问常用目录

4.1、static var applicationDirectory: URL

4.2、static var applicationSupportDirectory: URL

4.3、static var cachesDirectory: URL

4.4、static var desktopDirectory: URL

4.5、static var documentsDirectory: URL

4.6、static var downloadsDirectory: URL

4.7、static var libraryDirectory: URL

4.8、static var moviesDirectory: URL

4.9、static var musicDirectory: URL

4.10、static var picturesDirectory: URL

4.11、static var sharedPublicDirectory: URL

4.12、static var temporaryDirectory: URL

4.13、static var trashDirectory: URL

4.14、static var userDirectory: URL

5、访问家目录和用户目录

5.1、static func currentDirectory() -> URL

5.2、static var homeDirectory: URL

5.3、static func homeDirectory(forUser: String) -> URL?

6、添加路径组件Adding path components

添加方法分为append和appending两种,append类方法是在原有url上追加,appending类方法会产生一个新的URL。

6.1、基础使用

func append<S>(path: S, directoryHint: URL.DirectoryHint)
Appends a path to the URL, with a hint for handling directory awareness.

func append<S>(component: S, directoryHint: URL.DirectoryHint)
Appends a path component to the URL, with a hint for handling directory awareness.

func appending<S>(path: S, directoryHint: URL.DirectoryHint) -> URL
Returns a URL by appending the specified path to the URL, with a hint for handling directory awareness.

func appending<S>(component: S, directoryHint: URL.DirectoryHint) -> URL
Returns a URL by appending the specified path component to the URL, with a hint for handling directory awareness.

6.2、多路径追加

func append<S>(components: S..., directoryHint: URL.DirectoryHint)
Appends multiple path components to the URL, with a hint for handling directory awareness.

func appending<S>(components: S..., directoryHint: URL.DirectoryHint) -> URL
Returns a new URL by appending multiple path components to the URL, with a hint for handling directory awareness.

6.3、追加String

func appendPathComponent(String, conformingTo: UTType)
Appends a path component to the URL that conforms to a uniform type identifier.

func appendingPathComponent(String, conformingTo: UTType) -> URL
Returns a URL by appending the specified path component that conforms to a uniform type identifier.

7、添加路径扩展Adding a path extension

添加路径扩展同上面的添加路径组件一样,分为append和appending两类。从参数类型上类分,又分为两类。

7.1、添加String类型的路径扩展

func appendPathExtension(String)
Appends the specified path extension to self.

func appendingPathExtension(String) -> URL
Returns a URL by appending the specified path extension to self.

7.2、添加UTType类型的路径扩展

func appendPathExtension(for: UTType)
Appends the preferred path extension for the type you specify.

func appendingPathExtension(for: UTType) -> URL
Returns a URL by appending the preferred path extension for the type you specify to the URL’s last path component.

8、移除路径组件Removing path components

func deleteLastPathComponent()
Returns a URL constructed by removing the last path component of self.

func deletingLastPathComponent() -> URL
Returns a URL constructed by removing the last path component of self.

9、移除路径扩展Removing a path extension

func deletePathExtension()
Returns a URL constructed by removing any path extension.

func deletingPathExtension() -> URL
Returns a URL constructed by removing any path extension.

 

 

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接