Alamofire.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. //
  2. // Alamofire.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. /// Global namespace containing API for the `default` `Session` instance.
  26. public enum AF {
  27. // MARK: - Data Request
  28. /// Creates a `DataRequest` using `Session.default` to retrieve the contents of the specified `url` using the
  29. /// `method`, `parameters`, `encoding`, and `headers` provided.
  30. ///
  31. /// - Parameters:
  32. /// - url: The `URLConvertible` value.
  33. /// - method: The `HTTPMethod`, `.get` by default.
  34. /// - parameters: The `Parameters`, `nil` by default.
  35. /// - encoding: The `ParameterEncoding`, `URLEncoding.default` by default.
  36. /// - headers: The `HTTPHeaders`, `nil` by default.
  37. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  38. ///
  39. /// - Returns: The created `DataRequest`.
  40. public static func request(_ url: URLConvertible,
  41. method: HTTPMethod = .get,
  42. parameters: Parameters? = nil,
  43. encoding: ParameterEncoding = URLEncoding.default,
  44. headers: HTTPHeaders? = nil,
  45. interceptor: RequestInterceptor? = nil) -> DataRequest {
  46. return Session.default.request(url,
  47. method: method,
  48. parameters: parameters,
  49. encoding: encoding,
  50. headers: headers,
  51. interceptor: interceptor)
  52. }
  53. /// Creates a `DataRequest` using `Session.default` to retrieve the contents of the specified `url` using the
  54. /// `method`, `parameters`, `encoding`, and `headers` provided.
  55. ///
  56. /// - Parameters:
  57. /// - url: The `URLConvertible` value.
  58. /// - method: The `HTTPMethod`, `.get` by default.
  59. /// - parameters: The `Encodable` parameters, `nil` by default.
  60. /// - encoding: The `ParameterEncoder`, `URLEncodedFormParameterEncoder.default` by default.
  61. /// - headers: The `HTTPHeaders`, `nil` by default.
  62. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  63. ///
  64. /// - Returns: The created `DataRequest`.
  65. public static func request<Parameters: Encodable>(_ url: URLConvertible,
  66. method: HTTPMethod = .get,
  67. parameters: Parameters? = nil,
  68. encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
  69. headers: HTTPHeaders? = nil,
  70. interceptor: RequestInterceptor? = nil) -> DataRequest {
  71. return Session.default.request(url,
  72. method: method,
  73. parameters: parameters,
  74. encoder: encoder,
  75. headers: headers,
  76. interceptor: interceptor)
  77. }
  78. /// Creates a `DataRequest` using `Session.default` to execute the specified `urlRequest`.
  79. ///
  80. /// - Parameters:
  81. /// - urlRequest: The `URLRequestConvertible` value.
  82. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  83. ///
  84. /// - Returns: The created `DataRequest`.
  85. public static func request(_ urlRequest: URLRequestConvertible, interceptor: RequestInterceptor? = nil) -> DataRequest {
  86. return Session.default.request(urlRequest, interceptor: interceptor)
  87. }
  88. // MARK: - Download Request
  89. /// Creates a `DownloadRequest` using `Session.default` to download the contents of the specified `url` to
  90. /// the provided `destination` using the `method`, `parameters`, `encoding`, and `headers` provided.
  91. ///
  92. /// If `destination` is not specified, the download will be moved to a temporary location determined by Alamofire.
  93. ///
  94. /// - Parameters:
  95. /// - url: The `URLConvertible` value.
  96. /// - method: The `HTTPMethod`, `.get` by default.
  97. /// - parameters: The `Parameters`, `nil` by default.
  98. /// - encoding: The `ParameterEncoding`, `URLEncoding.default` by default.
  99. /// - headers: The `HTTPHeaders`, `nil` by default.
  100. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  101. /// - destination: The `DownloadRequest.Destination` closure used the determine the destination of the
  102. /// downloaded file. `nil` by default.
  103. ///
  104. /// - Returns: The created `DownloadRequest`.
  105. public static func download(_ url: URLConvertible,
  106. method: HTTPMethod = .get,
  107. parameters: Parameters? = nil,
  108. encoding: ParameterEncoding = URLEncoding.default,
  109. headers: HTTPHeaders? = nil,
  110. interceptor: RequestInterceptor? = nil,
  111. to destination: DownloadRequest.Destination? = nil) -> DownloadRequest {
  112. return Session.default.download(url,
  113. method: method,
  114. parameters: parameters,
  115. encoding: encoding,
  116. headers: headers,
  117. interceptor: interceptor,
  118. to: destination)
  119. }
  120. /// Creates a `DownloadRequest` using `Session.default` to download the contents of the specified `url` to the
  121. /// provided `destination` using the `method`, encodable `parameters`, `encoder`, and `headers` provided.
  122. ///
  123. /// - Note: If `destination` is not specified, the download will be moved to a temporary location determined by
  124. /// Alamofire.
  125. ///
  126. /// - Parameters:
  127. /// - url: The `URLConvertible` value.
  128. /// - method: The `HTTPMethod`, `.get` by default.
  129. /// - parameters: The `Encodable` parameters, `nil` by default.
  130. /// - encoder: The `ParameterEncoder`, `URLEncodedFormParameterEncoder.default` by default.
  131. /// - headers: The `HTTPHeaders`, `nil` by default.
  132. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  133. /// - destination: The `DownloadRequest.Destination` closure used the determine the destination of the
  134. /// downloaded file. `nil` by default.
  135. ///
  136. /// - Returns: The created `DownloadRequest`.
  137. public static func download<Parameters: Encodable>(_ url: URLConvertible,
  138. method: HTTPMethod = .get,
  139. parameters: Parameters? = nil,
  140. encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
  141. headers: HTTPHeaders? = nil,
  142. interceptor: RequestInterceptor? = nil,
  143. to destination: DownloadRequest.Destination? = nil) -> DownloadRequest {
  144. return Session.default.download(url,
  145. method: method,
  146. parameters: parameters,
  147. encoder: encoder,
  148. headers: headers,
  149. interceptor: interceptor,
  150. to: destination)
  151. }
  152. // MARK: URLRequest
  153. /// Creates a `DownloadRequest` using `Session.default` to execute the specified `urlRequest` and download
  154. /// the result to the provided `destination`.
  155. ///
  156. /// - Parameters:
  157. /// - urlRequest: The `URLRequestConvertible` value.
  158. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  159. /// - destination: The `DownloadRequest.Destination` closure used the determine the destination of the
  160. /// downloaded file. `nil` by default.
  161. ///
  162. /// - Returns: The created `DownloadRequest`.
  163. public static func download(_ urlRequest: URLRequestConvertible,
  164. interceptor: RequestInterceptor? = nil,
  165. to destination: DownloadRequest.Destination? = nil) -> DownloadRequest {
  166. return Session.default.download(urlRequest, interceptor: interceptor, to: destination)
  167. }
  168. // MARK: Resume Data
  169. /// Creates a `DownloadRequest` using the `Session.default` from the `resumeData` produced from a previous
  170. /// `DownloadRequest` cancellation to retrieve the contents of the original request and save them to the `destination`.
  171. ///
  172. /// - Note: If `destination` is not specified, the download will be moved to a temporary location determined by
  173. /// Alamofire.
  174. ///
  175. /// - Note: On some versions of all Apple platforms (iOS 10 - 10.2, macOS 10.12 - 10.12.2, tvOS 10 - 10.1, watchOS 3 - 3.1.1),
  176. /// `resumeData` is broken on background URL session configurations. There's an underlying bug in the `resumeData`
  177. /// generation logic where the data is written incorrectly and will always fail to resume the download. For more
  178. /// information about the bug and possible workarounds, please refer to the [this Stack Overflow post](http://stackoverflow.com/a/39347461/1342462).
  179. ///
  180. /// - Parameters:
  181. /// - resumeData: The resume `Data`. This is an opaque blob produced by `URLSessionDownloadTask` when a task is
  182. /// cancelled. See [Apple's documentation](https://developer.apple.com/documentation/foundation/urlsessiondownloadtask/1411634-cancel)
  183. /// for more information.
  184. /// - interceptor: The `RequestInterceptor`, `nil` by default.
  185. /// - destination: The `DownloadRequest.Destination` closure used to determine the destination of the downloaded
  186. /// file. `nil` by default.
  187. ///
  188. /// - Returns: The created `DownloadRequest`.
  189. public static func download(resumingWith resumeData: Data,
  190. interceptor: RequestInterceptor? = nil,
  191. to destination: DownloadRequest.Destination? = nil) -> DownloadRequest {
  192. return Session.default.download(resumingWith: resumeData, interceptor: interceptor, to: destination)
  193. }
  194. // MARK: - Upload Request
  195. // MARK: Data
  196. /// Creates an `UploadRequest` for the given `Data`, `URLRequest` components, and `RequestInterceptor`.
  197. ///
  198. /// - Parameters:
  199. /// - data: The `Data` to upload.
  200. /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`.
  201. /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default.
  202. /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default.
  203. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  204. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  205. /// default.
  206. ///
  207. /// - Returns: The created `UploadRequest`.
  208. public static func upload(_ data: Data,
  209. to convertible: URLConvertible,
  210. method: HTTPMethod = .post,
  211. headers: HTTPHeaders? = nil,
  212. interceptor: RequestInterceptor? = nil,
  213. fileManager: FileManager = .default) -> UploadRequest {
  214. return Session.default.upload(data,
  215. to: convertible,
  216. method: method,
  217. headers: headers,
  218. interceptor: interceptor,
  219. fileManager: fileManager)
  220. }
  221. /// Creates an `UploadRequest` for the given `Data` using the `URLRequestConvertible` value and `RequestInterceptor`.
  222. ///
  223. /// - Parameters:
  224. /// - data: The `Data` to upload.
  225. /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`.
  226. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  227. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  228. /// default.
  229. ///
  230. /// - Returns: The created `UploadRequest`.
  231. public static func upload(_ data: Data,
  232. with convertible: URLRequestConvertible,
  233. interceptor: RequestInterceptor? = nil,
  234. fileManager: FileManager = .default) -> UploadRequest {
  235. return Session.default.upload(data, with: convertible, interceptor: interceptor, fileManager: fileManager)
  236. }
  237. // MARK: File
  238. /// Creates an `UploadRequest` for the file at the given file `URL`, using a `URLRequest` from the provided
  239. /// components and `RequestInterceptor`.
  240. ///
  241. /// - Parameters:
  242. /// - fileURL: The `URL` of the file to upload.
  243. /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`.
  244. /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default.
  245. /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default.
  246. /// - interceptor: `RequestInterceptor` value to be used by the returned `UploadRequest`. `nil` by default.
  247. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  248. /// default.
  249. ///
  250. /// - Returns: The created `UploadRequest`.
  251. public static func upload(_ fileURL: URL,
  252. to convertible: URLConvertible,
  253. method: HTTPMethod = .post,
  254. headers: HTTPHeaders? = nil,
  255. interceptor: RequestInterceptor? = nil,
  256. fileManager: FileManager = .default) -> UploadRequest {
  257. return Session.default.upload(fileURL,
  258. to: convertible,
  259. method: method,
  260. headers: headers,
  261. interceptor: interceptor,
  262. fileManager: fileManager)
  263. }
  264. /// Creates an `UploadRequest` for the file at the given file `URL` using the `URLRequestConvertible` value and
  265. /// `RequestInterceptor`.
  266. ///
  267. /// - Parameters:
  268. /// - fileURL: The `URL` of the file to upload.
  269. /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`.
  270. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  271. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  272. /// default.
  273. ///
  274. /// - Returns: The created `UploadRequest`.
  275. public static func upload(_ fileURL: URL,
  276. with convertible: URLRequestConvertible,
  277. interceptor: RequestInterceptor? = nil,
  278. fileManager: FileManager = .default) -> UploadRequest {
  279. return Session.default.upload(fileURL, with: convertible, interceptor: interceptor, fileManager: fileManager)
  280. }
  281. // MARK: InputStream
  282. /// Creates an `UploadRequest` from the `InputStream` provided using a `URLRequest` from the provided components and
  283. /// `RequestInterceptor`.
  284. ///
  285. /// - Parameters:
  286. /// - stream: The `InputStream` that provides the data to upload.
  287. /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`.
  288. /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default.
  289. /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default.
  290. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  291. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  292. /// default.
  293. ///
  294. /// - Returns: The created `UploadRequest`.
  295. public static func upload(_ stream: InputStream,
  296. to convertible: URLConvertible,
  297. method: HTTPMethod = .post,
  298. headers: HTTPHeaders? = nil,
  299. interceptor: RequestInterceptor? = nil,
  300. fileManager: FileManager = .default) -> UploadRequest {
  301. return Session.default.upload(stream,
  302. to: convertible,
  303. method: method,
  304. headers: headers,
  305. interceptor: interceptor,
  306. fileManager: fileManager)
  307. }
  308. /// Creates an `UploadRequest` from the provided `InputStream` using the `URLRequestConvertible` value and
  309. /// `RequestInterceptor`.
  310. ///
  311. /// - Parameters:
  312. /// - stream: The `InputStream` that provides the data to upload.
  313. /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`.
  314. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  315. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  316. /// default.
  317. ///
  318. /// - Returns: The created `UploadRequest`.
  319. public static func upload(_ stream: InputStream,
  320. with convertible: URLRequestConvertible,
  321. interceptor: RequestInterceptor? = nil,
  322. fileManager: FileManager = .default) -> UploadRequest {
  323. return Session.default.upload(stream, with: convertible, interceptor: interceptor, fileManager: fileManager)
  324. }
  325. // MARK: MultipartFormData
  326. /// Creates an `UploadRequest` for the multipart form data built using a closure and sent using the provided
  327. /// `URLRequest` components and `RequestInterceptor`.
  328. ///
  329. /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative
  330. /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
  331. /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
  332. /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
  333. /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
  334. /// used for larger payloads such as video content.
  335. ///
  336. /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
  337. /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
  338. /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
  339. /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
  340. /// technique was used.
  341. ///
  342. /// - Parameters:
  343. /// - multipartFormData: `MultipartFormData` building closure.
  344. /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`.
  345. /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or
  346. /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by
  347. /// default.
  348. /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default.
  349. /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default.
  350. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  351. /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is
  352. /// written to disk before being uploaded. `.default` instance by default.
  353. ///
  354. /// - Returns: The created `UploadRequest`.
  355. public static func upload(multipartFormData: @escaping (MultipartFormData) -> Void,
  356. to url: URLConvertible,
  357. usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold,
  358. method: HTTPMethod = .post,
  359. headers: HTTPHeaders? = nil,
  360. interceptor: RequestInterceptor? = nil,
  361. fileManager: FileManager = .default) -> UploadRequest {
  362. return Session.default.upload(multipartFormData: multipartFormData,
  363. to: url,
  364. usingThreshold: encodingMemoryThreshold,
  365. method: method,
  366. headers: headers,
  367. interceptor: interceptor,
  368. fileManager: fileManager)
  369. }
  370. /// Creates an `UploadRequest` using a `MultipartFormData` building closure, the provided `URLRequestConvertible`
  371. /// value, and a `RequestInterceptor`.
  372. ///
  373. /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative
  374. /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
  375. /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
  376. /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
  377. /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
  378. /// used for larger payloads such as video content.
  379. ///
  380. /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
  381. /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
  382. /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
  383. /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
  384. /// technique was used.
  385. ///
  386. /// - Parameters:
  387. /// - multipartFormData: `MultipartFormData` building closure.
  388. /// - request: `URLRequestConvertible` value to be used to create the `URLRequest`.
  389. /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or
  390. /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by
  391. /// default.
  392. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  393. /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is
  394. /// written to disk before being uploaded. `.default` instance by default.
  395. ///
  396. /// - Returns: The created `UploadRequest`.
  397. public static func upload(multipartFormData: @escaping (MultipartFormData) -> Void,
  398. with request: URLRequestConvertible,
  399. usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold,
  400. interceptor: RequestInterceptor? = nil,
  401. fileManager: FileManager = .default) -> UploadRequest {
  402. return Session.default.upload(multipartFormData: multipartFormData,
  403. with: request,
  404. usingThreshold: encodingMemoryThreshold,
  405. interceptor: interceptor,
  406. fileManager: fileManager)
  407. }
  408. /// Creates an `UploadRequest` for the prebuilt `MultipartFormData` value using the provided `URLRequest` components
  409. /// and `RequestInterceptor`.
  410. ///
  411. /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative
  412. /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
  413. /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
  414. /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
  415. /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
  416. /// used for larger payloads such as video content.
  417. ///
  418. /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
  419. /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
  420. /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
  421. /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
  422. /// technique was used.
  423. ///
  424. /// - Parameters:
  425. /// - multipartFormData: `MultipartFormData` instance to upload.
  426. /// - url: `URLConvertible` value to be used as the `URLRequest`'s `URL`.
  427. /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or
  428. /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by
  429. /// default.
  430. /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default.
  431. /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default.
  432. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  433. /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is
  434. /// written to disk before being uploaded. `.default` instance by default.
  435. ///
  436. /// - Returns: The created `UploadRequest`.
  437. public static func upload(multipartFormData: MultipartFormData,
  438. to url: URLConvertible,
  439. usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold,
  440. method: HTTPMethod = .post,
  441. headers: HTTPHeaders? = nil,
  442. interceptor: RequestInterceptor? = nil,
  443. fileManager: FileManager = .default) -> UploadRequest {
  444. return Session.default.upload(multipartFormData: multipartFormData,
  445. to: url,
  446. usingThreshold: encodingMemoryThreshold,
  447. method: method,
  448. headers: headers,
  449. interceptor: interceptor,
  450. fileManager: fileManager)
  451. }
  452. /// Creates an `UploadRequest` for the prebuilt `MultipartFormData` value using the providing `URLRequestConvertible`
  453. /// value and `RequestInterceptor`.
  454. ///
  455. /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative
  456. /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
  457. /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
  458. /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
  459. /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
  460. /// used for larger payloads such as video content.
  461. ///
  462. /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
  463. /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
  464. /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
  465. /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
  466. /// technique was used.
  467. ///
  468. /// - Parameters:
  469. /// - multipartFormData: `MultipartFormData` instance to upload.
  470. /// - request: `URLRequestConvertible` value to be used to create the `URLRequest`.
  471. /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or
  472. /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by
  473. /// default.
  474. /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default.
  475. /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by
  476. /// default.
  477. ///
  478. /// - Returns: The created `UploadRequest`.
  479. public static func upload(multipartFormData: MultipartFormData,
  480. with request: URLRequestConvertible,
  481. usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold,
  482. interceptor: RequestInterceptor? = nil,
  483. fileManager: FileManager = .default) -> UploadRequest {
  484. return Session.default.upload(multipartFormData: multipartFormData,
  485. with: request,
  486. usingThreshold: encodingMemoryThreshold,
  487. interceptor: interceptor,
  488. fileManager: fileManager)
  489. }
  490. }