let url = URL(string: "https://www.duidaima.com")!这个强制解包看起来就很不优雅,而且在代码里到处都是感叹号。有个简单的扩展可以解决这个问题:
extension URL { init(_ string: StaticString) { self.init(string: "\(string)")! } } let unwrappedURL = URL("https://www.duidaima.com")这样就干净多了,不用满屏幕的感叹号。不过提醒一下,不建议这样使用,这样做本质上不安全,因为 URL 可能为空。
print(unwrappedURL.absoluteString) // 输出: https://www.apple.com构建相对 URL,API 开发必备技能
let category = "swift" let baseURL = URL(string: "https://www.apple.com")! let blogURL = URL(string: category, relativeTo: baseURL)! print(blogURL.absoluteString) // 输出: https://www.apple.com/swift这种方式比字符串拼接要安全得多,不用担心路径分隔符的问题。
let twitterURL = URL(string: "https://twitter.com/twannl/photo.png")! print(twitterURL.host!) // 输出: twitter.com print(twitterURL.scheme!) // 输出: https print(twitterURL.path) // 输出: /twannl/photo.png print(twitterURL.pathExtension) // 输出: png print(twitterURL.lastPathComponent) // 输出: photo.png查询参数处理,URLComponents 是神器
let avatarURL = "https://twitter.com/twannl/photo.png?width=200&height=200" let components = URLComponents(string: avatarURL)! print(components.query!) // width=200&height=200 print(components.queryItems!) // [width=200, height=200]但这样获取特定参数值还是很麻烦,可以写个扩展:
extension Collection where Element == URLQueryItem { subscript(_ name: String) -> String? { first(where: { $0.name == name })?.value } } let width = components.queryItems!["width"] let height = components.queryItems!["height"]构建带参数的 URL,字典转查询参数
let parameters = [ "width": 500, "height": 500 ] var avatarURLComponents = URLComponents(string: "https://twitter.com/twannl/photo.png")! avatarURLComponents.queryItems = parameters.map { (key, value) in URLQueryItem(name: key, value: String(value)) } print(avatarURLComponents.url!) // 输出: https://twitter.com/twannl/photo.png?width=500&height=500为了让代码更简洁,可以写个 Array 的扩展:
extension Array where Element == URLQueryItem { init<T: LosslessStringConvertible>(_ dictionary: [String: T]) { self = dictionary.map { (key, value) in URLQueryItem(name: key, value: String(value)) } } } // 使用起来就简单多了 avatarURLComponents.queryItems = .init(parameters)文件 URL 操作,本地文件处理必备
let remoteURL = URL(string: "https://www.twitter.com/avatar.jpg")! let fileURL = URL(string: "file:///users/antoine/avatar.jpg")! print(remoteURL.isFileURL) // false print(fileURL.isFileURL) // true获取文件名和扩展名也很简单:
print(fileURL.pathExtension) // jpg print(fileURL.deletingPathExtension().lastPathComponent) // avatar实际开发中的应用场景
文件路径分隔符:不同平台的路径分隔符不同,用 URL 处理更安全