Swift和SwiftUI编写代码的10条有用提示之 10 使用枚举而不是原始字符串安全地构造URL

使用枚举而不是原始字符串安全地构造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

发表回复