Skip to content

Commit 2d4e139

Browse files
authored
Storage async await (#8289)
1 parent d550a72 commit 2d4e139

File tree

8 files changed

+586
-87
lines changed

8 files changed

+586
-87
lines changed

FirebaseCombineSwift/Sources/Storage/StorageReference+Combine.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
/// The publisher will emit events on the **main** thread.
8383
///
8484
/// - Parameters:
85-
/// - size: The maximum size in bytes to download. If the download exceeds this size
85+
/// - size: The maximum size in bytes to download. If the download exceeds this size,
8686
/// the task will be cancelled and an error will be returned.
8787
///
8888
/// - Returns: A publisher emitting a `Data` instance. The publisher will emit on the *main* thread.

FirebaseStorage/Sources/Public/FirebaseStorage/FIRStorageReference.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ NS_SWIFT_NAME(putData(_:metadata:));
178178
* Asynchronously downloads the object at the FIRStorageReference to an NSData object in memory.
179179
* An NSData of the provided max size will be allocated, so ensure that the device has enough free
180180
* memory to complete the download. For downloading large files, writeToFile may be a better option.
181-
* @param size The maximum size in bytes to download. If the download exceeds this size
181+
* @param size The maximum size in bytes to download. If the download exceeds this size,
182182
* the task will be cancelled and an error will be returned.
183183
* @param completion A completion block that either returns the object data on success,
184184
* or an error on failure.
@@ -194,7 +194,7 @@ NS_SWIFT_NAME(putData(_:metadata:));
194194
/**
195195
* Asynchronously retrieves a long lived download URL with a revokable token.
196196
* This can be used to share the file with others, but can be revoked by a developer
197-
* in the Firebase Console if desired.
197+
* in the Firebase Console.
198198
* @param completion A completion block that either returns the URL on success,
199199
* or an error on failure.
200200
*/

FirebaseStorageSwift/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 8.5.0-beta
2+
- Added four APIs to augment automatically generated `async/await` APIs. See
3+
details via Xcode completion and at the
4+
[source](https://github.com/firebase/firebase-ios-sdk/blob/96d60a6d472b6fed1651d5e7a0e7495230c220ec/FirebaseStorageSwift/Sources/AsyncAwait.swift).
5+
Feedback appreciated about Firebase and `async/await`. (#8289)
6+
17
# v0.1
28
- Initial public beta release. Extends the Storage Reference API with the Swift
39
Result type for all APIs that return an optional value and optional Error.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2021 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+
15+
import FirebaseStorage
16+
17+
#if swift(>=5.5)
18+
@available(iOS 15, *)
19+
public extension StorageReference {
20+
/// Asynchronously downloads the object at the StorageReference to a Data object in memory.
21+
/// A Data object of the provided max size will be allocated, so ensure that the device has
22+
/// enough free memory to complete the download. For downloading large files, the `write`
23+
/// API may be a better option.
24+
///
25+
/// - Parameters:
26+
/// - size: The maximum size in bytes to download. If the download exceeds this size,
27+
/// the task will be cancelled and an error will be thrown.
28+
/// - Returns: Data object.
29+
func data(maxSize: Int64) async throws -> Data {
30+
typealias DataContinuation = CheckedContinuation<Data, Error>
31+
return try await withCheckedThrowingContinuation { (continuation: DataContinuation) in
32+
// TODO: Use task to handle progress and cancellation.
33+
_ = self.getData(maxSize: maxSize) { result in
34+
continuation.resume(with: result)
35+
}
36+
}
37+
}
38+
39+
/// Asynchronously uploads data to the currently specified StorageReference.
40+
/// This is not recommended for large files, and one should instead upload a file from disk
41+
/// from the Firebase Console.
42+
///
43+
/// - Parameters:
44+
/// - uploadData: The Data to upload.
45+
/// - metadata: Optional StorageMetadata containing additional information (MIME type, etc.)
46+
/// about the object being uploaded.
47+
/// - Returns: StorageMetadata with additional information about the object being uploaded.
48+
func putDataAsync(_ uploadData: Data,
49+
metadata: StorageMetadata? = nil) async throws -> StorageMetadata {
50+
typealias MetadataContinuation = CheckedContinuation<StorageMetadata, Error>
51+
return try await withCheckedThrowingContinuation { (continuation: MetadataContinuation) in
52+
// TODO: Use task to handle progress and cancellation.
53+
_ = self.putData(uploadData, metadata: metadata) { result in
54+
continuation.resume(with: result)
55+
}
56+
}
57+
}
58+
59+
/// Asynchronously uploads a file to the currently specified StorageReference.
60+
///
61+
/// - Parameters:
62+
/// - url: A URL representing the system file path of the object to be uploaded.
63+
/// - metadata: Optional StorageMetadata containing additional information (MIME type, etc.)
64+
/// about the object being uploaded.
65+
/// - Returns: StorageMetadata with additional information about the object being uploaded.
66+
func putFileAsync(from url: URL,
67+
metadata: StorageMetadata? = nil) async throws -> StorageMetadata {
68+
typealias MetadataContinuation = CheckedContinuation<StorageMetadata, Error>
69+
return try await withCheckedThrowingContinuation { (continuation: MetadataContinuation) in
70+
// TODO: Use task to handle progress and cancellation.
71+
_ = self.putFile(from: url, metadata: metadata) { result in
72+
continuation.resume(with: result)
73+
}
74+
}
75+
}
76+
77+
/// Asynchronously downloads the object at the current path to a specified system filepath.
78+
///
79+
/// - Parameters:
80+
/// - fileUrl: A URL representing the system file path of the object to be uploaded.
81+
/// - Returns: URL pointing to the file path of the downloaded file.
82+
func writeAsync(toFile fileURL: URL) async throws -> URL {
83+
typealias URLContinuation = CheckedContinuation<URL, Error>
84+
return try await withCheckedThrowingContinuation { (continuation: URLContinuation) in
85+
// TODO: Use task to handle progress and cancellation.
86+
_ = self.write(toFile: fileURL) { result in
87+
continuation.resume(with: result)
88+
}
89+
}
90+
}
91+
}
92+
#endif

FirebaseStorageSwift/Sources/SwiftAPIExtension.swift renamed to FirebaseStorageSwift/Sources/Result.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
import FirebaseStorage
1616

17+
private enum DataError: Error {
18+
case internalInconsistency // Thrown when both value and error are nil.
19+
}
20+
1721
/// Generates a closure that returns a `Result` type from a closure that returns an optional type
1822
/// and `Error`.
1923
///
@@ -31,19 +35,15 @@ private func getResultCallback<T>(completion: @escaping (Result<T, Error>) -> Vo
3135
} else if let error = error {
3236
completion(.failure(error))
3337
} else {
34-
completion(.failure(NSError(domain: "FirebaseStorageSwift",
35-
code: -1,
36-
userInfo: [NSLocalizedDescriptionKey:
37-
"InternalError - Return type and Error code both nil in " +
38-
"Storage Result generator"])))
38+
completion(.failure(DataError.internalInconsistency))
3939
}
4040
}
4141
}
4242

4343
public extension StorageReference {
4444
/// Asynchronously retrieves a long lived download URL with a revokable token.
4545
/// This can be used to share the file with others, but can be revoked by a developer
46-
/// in the Firebase Console if desired.
46+
/// in the Firebase Console.
4747
///
4848
/// - Parameters:
4949
/// - completion: A completion block returning a `Result` enum with either a URL or an `Error`.
@@ -53,7 +53,7 @@ public extension StorageReference {
5353

5454
/// Asynchronously downloads the object at the `StorageReference` to a `Data` object.
5555
/// A `Data` of the provided max size will be allocated, so ensure that the device has enough
56-
/// memory to complete. For downloading large files, writeToFile may be a better option.
56+
/// memory to complete. For downloading large files, the `write` API may be a better option.
5757

5858
/// - Parameters:
5959
/// - maxSize: The maximum size in bytes to download.

0 commit comments

Comments
 (0)