使用枚举而不是原始字符串安全地构造URL
以下是安全地创建对原始字符串的依赖程度最低的URL的方法。
看起来可能很多,但我们基本上是将枚举与原始类型的Stringwith结合在一起URLComponents。此结构提供了一种单独添加方案,主机和路径组件的方法,而不是传递可能失败的原始字符串。
我们不是依靠硬编码的字符串来获取URL中正确数量的点和斜杠,而是依靠URLComponents结构来为我们完成此操作。
因此,除了子域名和域名之间的点(例如中的maps.google.com)外,我们添加的所有组件都不会带有斜线或点。
import Foundation
//SwiftUI技术交流QQ群:518696470
extension URL {
enum Scheme: String { case http, https }
enum Subdomain: String { case maps, translate, noSubdomain = "" }
enum DomainName: String { case apple, google }
enum DomainExtension: String { case com, couk = "co.uk" }
enum PathComponent: String { case accessibility }
/// Create a URL using cases from the enums above
/// - Parameters:
/// - scheme: Could be https or a custom URL scheme
/// - subdomain: An optional part of the host name that is separated from the domain name automatically (so no '.' should be given in the parameter)
/// - domainName: The main part of the host name that describes the website (without the '.' or extension)
/// - domainExtension: The extension after the host name (without the '.')
/// - pathComponents: The directory path that will be separated by slashes automatically (so no slashes should be given in the parameter)
init?(scheme: Scheme, subdomain: Subdomain? = .noSubdomain, domainName: DomainName, domainExtension: DomainExtension, pathComponents: [PathComponent]? = []) {
//The URL will be constructed from components
var urlComponents = URLComponents()
//Add scheme
urlComponents.scheme = scheme.rawValue
//Add hostname
var hostname = [String]()
if let subdomain = subdomain, !subdomain.rawValue.isEmpty {
hostname = [subdomain.rawValue, domainName.rawValue, domainExtension.rawValue]
}
else { hostname = [domainName.rawValue, domainExtension.rawValue] }
urlComponents.host = hostname.joined(separator: ".")
//Create URL and add path components if any exist
var url = urlComponents.url
if let pathComponents = pathComponents {
for pathComponent in pathComponents {
url?.appendPathComponent(pathComponent.rawValue)
}
}
//Create URL string
guard let urlString = url?.absoluteString else {
return nil
}
//Use existing initialiser with the string
self.init(string: urlString)
}
}
//URL with path components
let appleURL = URL(scheme: .https, domainName: .apple, domainExtension: .com, pathComponents: [.accessibility])
//URL with subdomain
let googleURL = URL(scheme: .https, subdomain: .maps, domainName: .google, domainExtension: .com)
//URL without either
let googleUKURL = URL(scheme: .https, domainName: .google, domainExtension: .couk)
加入我们一起学习SwiftUI
QQ:3365059189
SwiftUI技术交流QQ群:518696470
教程网站:www.openswiftui.com