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.