Result.swift 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import Foundation
  15. /// Generates a closure that returns a `Result` type from a closure that returns an optional type
  16. /// and `Error`.
  17. ///
  18. /// - Parameters:
  19. /// - completion: A completion block returning a `Result` enum with either a generic object or
  20. /// an `Error`.
  21. /// - Returns: A closure parameterized with an optional generic and optional `Error` to match
  22. /// Objective-C APIs.
  23. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  24. private func getResultCallback<T>(completion: @escaping @Sendable (Result<T, Error>) -> Void)
  25. -> @Sendable (_: T?,
  26. _: Error?)
  27. -> Void {
  28. return { (value: T?, error: Error?) in
  29. if let value {
  30. completion(.success(value))
  31. } else if let error {
  32. completion(.failure(error))
  33. } else {
  34. completion(.failure(StorageError.internalError(
  35. message: "Internal failure in getResultCallback"
  36. )))
  37. }
  38. }
  39. }
  40. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  41. public extension StorageReference {
  42. /// Asynchronously retrieves a long lived download URL with a revokable token.
  43. ///
  44. /// This can be used to share the file with others, but can be revoked by a developer
  45. /// in the Firebase Console.
  46. ///
  47. /// - Parameters:
  48. /// - completion: A completion block returning a `Result` enum with either a URL or an `Error`.
  49. func downloadURL(completion: @escaping @Sendable (Result<URL, Error>) -> Void) {
  50. downloadURL(completion: getResultCallback(completion: completion))
  51. }
  52. /// Asynchronously downloads the object at the `StorageReference` to a `Data` object.
  53. ///
  54. /// A `Data` of the provided max size will be allocated, so ensure that the device has enough
  55. /// memory to complete. For downloading large files, the `write` API may be a better option.
  56. /// - Parameters:
  57. /// - maxSize: The maximum size in bytes to download.
  58. /// - completion: A completion block returning a `Result` enum with either a `Data` object or
  59. /// an `Error`.
  60. ///
  61. /// - Returns: A StorageDownloadTask that can be used to monitor or manage the download.
  62. @discardableResult
  63. func getData(maxSize: Int64, completion: @escaping @Sendable (Result<Data, Error>) -> Void)
  64. -> StorageDownloadTask {
  65. return getData(maxSize: maxSize, completion: getResultCallback(completion: completion))
  66. }
  67. /// Retrieves metadata associated with an object at the current path.
  68. ///
  69. /// - Parameters:
  70. /// - completion: A completion block which returns a `Result` enum with either the
  71. /// object metadata or an `Error`.
  72. func getMetadata(completion: @escaping @Sendable (Result<StorageMetadata, Error>) -> Void) {
  73. getMetadata(completion: getResultCallback(completion: completion))
  74. }
  75. /// Resumes a previous `list` call, starting after a pagination token.
  76. ///
  77. /// Returns the next set of items (files) and prefixes (folders) under this StorageReference.
  78. ///
  79. /// "/" is treated as a path delimiter. Firebase Storage does not support unsupported object
  80. /// paths that end with "/" or contain two consecutive "/"s. All invalid objects in GCS will be
  81. /// filtered.
  82. ///
  83. /// Only available for projects using Firebase Rules Version 2.
  84. ///
  85. /// - Parameters:
  86. /// - maxResults: The maximum number of results to return in a single page. Must be
  87. /// greater than 0 and at most 1000.
  88. /// - pageToken: A page token from a previous call to list.
  89. /// - completion: A completion handler that will be invoked with the next items and
  90. /// prefixes under the current StorageReference. It returns a `Result` enum
  91. /// with either the list or an `Error`.
  92. func list(maxResults: Int64,
  93. pageToken: String,
  94. completion: @escaping @Sendable (Result<StorageListResult, Error>) -> Void) {
  95. list(maxResults: maxResults,
  96. pageToken: pageToken,
  97. completion: getResultCallback(completion: completion))
  98. }
  99. /// List up to `maxResults` items (files) and prefixes (folders) under this StorageReference.
  100. ///
  101. /// "/" is treated as a path delimiter. Firebase Storage does not support unsupported object
  102. /// paths that end with "/" or contain two consecutive "/"s. All invalid objects in GCS will be
  103. /// filtered.
  104. ///
  105. /// Only available for projects using Firebase Rules Version 2.
  106. ///
  107. /// - Parameters:
  108. /// - maxResults: The maximum number of results to return in a single page. Must be
  109. /// greater than 0 and at most 1000.
  110. /// - completion: A completion handler that will be invoked with the next items and
  111. /// prefixes under the current `StorageReference`. It returns a `Result` enum
  112. /// with either the list or an `Error`.
  113. func list(maxResults: Int64,
  114. completion: @escaping @Sendable (Result<StorageListResult, Error>) -> Void) {
  115. list(maxResults: maxResults,
  116. completion: getResultCallback(completion: completion))
  117. }
  118. /// List all items (files) and prefixes (folders) under this StorageReference.
  119. ///
  120. /// This is a helper method for calling list() repeatedly until there are no more results.
  121. /// Consistency of the result is not guaranteed if objects are inserted or removed while this
  122. /// operation is executing. All results are buffered in memory.
  123. ///
  124. /// Only available for projects using Firebase Rules Version 2.
  125. ///
  126. /// - Parameters:
  127. /// - completion: A completion handler that will be invoked with all items and prefixes
  128. /// under the current StorageReference. It returns a `Result` enum with either the
  129. /// list or an `Error`.
  130. func listAll(completion: @escaping @Sendable (Result<StorageListResult, Error>) -> Void) {
  131. listAll(completion: getResultCallback(completion: completion))
  132. }
  133. /// Asynchronously uploads data to the currently specified `StorageReference`.
  134. /// This is not recommended for large files, and one should instead upload a file from disk.
  135. ///
  136. /// - Parameters:
  137. /// - uploadData: The `Data` to upload.
  138. /// - metadata: `StorageMetadata` containing additional information (MIME type, etc.)
  139. /// about the object being uploaded.
  140. /// - completion: A completion block that returns a `Result` enum with either the
  141. /// object metadata or an `Error`.
  142. ///
  143. /// - Returns: An instance of `StorageUploadTask`, which can be used to monitor or manage
  144. /// the upload.
  145. @discardableResult
  146. func putData(_ uploadData: Data,
  147. metadata: StorageMetadata? = nil,
  148. completion: @escaping @Sendable (Result<StorageMetadata, Error>) -> Void)
  149. -> StorageUploadTask {
  150. return putData(uploadData,
  151. metadata: metadata,
  152. completion: getResultCallback(completion: completion))
  153. }
  154. /// Asynchronously uploads a file to the currently specified `StorageReference`.
  155. ///
  156. /// - Parameters:
  157. /// - from: A URL representing the system file path of the object to be uploaded.
  158. /// - metadata: `StorageMetadata` containing additional information (MIME type, etc.)
  159. /// about the object being uploaded.
  160. /// - completion: A completion block that returns a `Result` enum with either the
  161. /// object metadata or an `Error`.
  162. ///
  163. /// - Returns: An instance of `StorageUploadTask`, which can be used to monitor or manage
  164. /// the upload.
  165. @discardableResult
  166. func putFile(from: URL,
  167. metadata: StorageMetadata? = nil,
  168. completion: @escaping @Sendable (Result<StorageMetadata, Error>) -> Void)
  169. -> StorageUploadTask {
  170. return putFile(from: from,
  171. metadata: metadata,
  172. completion: getResultCallback(completion: completion))
  173. }
  174. /// Updates the metadata associated with an object at the current path.
  175. ///
  176. /// - Parameters:
  177. /// - metadata: A `StorageMetadata` object with the metadata to update.
  178. /// - completion: A completion block which returns a `Result` enum with either the
  179. /// object metadata or an `Error`.
  180. func updateMetadata(_ metadata: StorageMetadata,
  181. completion: @escaping @Sendable (Result<StorageMetadata, Error>) -> Void) {
  182. updateMetadata(metadata, completion: getResultCallback(completion: completion))
  183. }
  184. /// Asynchronously downloads the object at the current path to a specified system filepath.
  185. ///
  186. /// - Parameters:
  187. /// - toFile: A file system URL representing the path the object should be downloaded to.
  188. /// - completion: A completion block that fires when the file download completes. The
  189. /// block returns a `Result` enum with either an NSURL pointing to the file
  190. /// path of the downloaded file or an `Error`.
  191. ///
  192. /// - Returns: A `StorageDownloadTask` that can be used to monitor or manage the download.
  193. @discardableResult
  194. func write(toFile: URL, completion: @escaping @Sendable (Result<URL, Error>)
  195. -> Void) -> StorageDownloadTask {
  196. return write(toFile: toFile, completion: getResultCallback(completion: completion))
  197. }
  198. }