URLConvertible+URLRequestConvertible.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //
  2. // URLConvertible+URLRequestConvertible.swift
  3. //
  4. // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Foundation
  25. /// Types adopting the `URLConvertible` protocol can be used to construct `URL`s, which can then be used to construct
  26. /// `URLRequests`.
  27. public protocol URLConvertible {
  28. /// Returns a `URL` from the conforming instance or throws.
  29. ///
  30. /// - Returns: The `URL` created from the instance.
  31. /// - Throws: Any error thrown while creating the `URL`.
  32. func asURL() throws -> URL
  33. }
  34. extension String: URLConvertible {
  35. /// Returns a `URL` if `self` can be used to initialize a `URL` instance, otherwise throws.
  36. ///
  37. /// - Returns: The `URL` initialized with `self`.
  38. /// - Throws: An `AFError.invalidURL` instance.
  39. public func asURL() throws -> URL {
  40. guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) }
  41. return url
  42. }
  43. }
  44. extension URL: URLConvertible {
  45. /// Returns `self`.
  46. public func asURL() throws -> URL { self }
  47. }
  48. extension URLComponents: URLConvertible {
  49. /// Returns a `URL` if the `self`'s `url` is not nil, otherwise throws.
  50. ///
  51. /// - Returns: The `URL` from the `url` property.
  52. /// - Throws: An `AFError.invalidURL` instance.
  53. public func asURL() throws -> URL {
  54. guard let url = url else { throw AFError.invalidURL(url: self) }
  55. return url
  56. }
  57. }
  58. // MARK: -
  59. /// Types adopting the `URLRequestConvertible` protocol can be used to safely construct `URLRequest`s.
  60. public protocol URLRequestConvertible {
  61. /// Returns a `URLRequest` or throws if an `Error` was encountered.
  62. ///
  63. /// - Returns: A `URLRequest`.
  64. /// - Throws: Any error thrown while constructing the `URLRequest`.
  65. func asURLRequest() throws -> URLRequest
  66. }
  67. extension URLRequestConvertible {
  68. /// The `URLRequest` returned by discarding any `Error` encountered.
  69. public var urlRequest: URLRequest? { try? asURLRequest() }
  70. }
  71. extension URLRequest: URLRequestConvertible {
  72. /// Returns `self`.
  73. public func asURLRequest() throws -> URLRequest { self }
  74. }
  75. // MARK: -
  76. extension URLRequest {
  77. /// Creates an instance with the specified `url`, `method`, and `headers`.
  78. ///
  79. /// - Parameters:
  80. /// - url: The `URLConvertible` value.
  81. /// - method: The `HTTPMethod`.
  82. /// - headers: The `HTTPHeaders`, `nil` by default.
  83. /// - Throws: Any error thrown while converting the `URLConvertible` to a `URL`.
  84. public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws {
  85. let url = try url.asURL()
  86. self.init(url: url)
  87. httpMethod = method.rawValue
  88. allHTTPHeaderFields = headers?.dictionary
  89. }
  90. }