Cloud Storage for Firebase 可让您快速轻松地从 Firebase 提供和管理的 Cloud Storage 存储桶中下载文件。
创建引用
如需下载某个文件,请先为要下载的文件创建一个 Cloud Storage 引用。
您可以通过将子路径附加到 Cloud Storage 存储桶的根目录来创建引用,也可以根据指向 Cloud Storage 中的对象的现有 gs://
或 https://
网址创建引用。
Swift
// Create a reference with an initial file path and name let pathReference = storage.reference(withPath: "images/stars.jpg") // Create a reference from a Google Cloud Storage URI let gsReference = storage.reference(forURL: "gs://<your-firebase-storage-bucket>/images/stars.jpg") // Create a reference from an HTTPS URL // Note that in the URL, characters are URL escaped! let httpsReference = storage.reference(forURL: "https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg")
Objective-C
// Create a reference with an initial file path and name FIRStorageReference *pathReference = [storage referenceWithPath:@"images/stars.jpg"]; // Create a reference from a Google Cloud Storage URI FIRStorageReference *gsReference = [storage referenceForURL:@"gs://<your-firebase-storage-bucket>/images/stars.jpg"]; // Create a reference from an HTTPS URL // Note that in the URL, characters are URL escaped! FIRStorageReference *httpsReference = [storage referenceForURL:@"https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg"];
下载文件
有了引用之后,可通过三种方法从 Cloud Storage 中下载文件:
- 下载到内存中的
NSData
- 下载到表示设备上某个文件的
NSURL
- 生成一个表示在线文件的
NSURL
下载至内存
使用 dataWithMaxSize:completion:
方法将文件下载到内存中的 NSData
对象。这是快速下载文件的最简单方法,但它必须将文件的全部内容加载到内存中。
如果您请求下载的文件大于应用的可用内存,应用将会崩溃。为了防止出现内存问题,请务必将大小上限设置为已知您的应用可以处理的数值,或使用其他下载方法。
Swift
// Create a reference to the file you want to download let islandRef = storageRef.child("images/island.jpg") // Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes) islandRef.getData(maxSize: 1 * 1024 * 1024) { data, error in if let error = error { // Uh-oh, an error occurred! } else { // Data for "images/island.jpg" is returned let image = UIImage(data: data!) } }
Objective-C
// Create a reference to the file you want to download FIRStorageReference *islandRef = [storageRef child:@"images/island.jpg"]; // Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes) [islandRef dataWithMaxSize:1 * 1024 * 1024 completion:^(NSData *data, NSError *error){ if (error != nil) { // Uh-oh, an error occurred! } else { // Data for "images/island.jpg" is returned UIImage *islandImage = [UIImage imageWithData:data]; } }];
下载至本地文件
writeToFile:completion:
方法可将文件直接下载至本地设备。如果用户希望离线时可以访问文件或希望在不同的应用中共享文件,请使用这种方法。writeToFile:completion:
会返回一个 FIRStorageDownloadTask
,您可以使用它来管理下载并监控下载状态。
Swift
// Create a reference to the file you want to download let islandRef = storageRef.child("images/island.jpg") // Create local filesystem URL let localURL = URL(string: "path/to/image")! // Download to the local filesystem let downloadTask = islandRef.write(toFile: localURL) { url, error in if let error = error { // Uh-oh, an error occurred! } else { // Local file URL for "images/island.jpg" is returned } }
Objective-C
// Create a reference to the file you want to download FIRStorageReference *islandRef = [storageRef child:@"images/island.jpg"]; // Create local filesystem URL NSURL *localURL = [NSURL URLWithString:@"path/to/image"]; // Download to the local filesystem FIRStorageDownloadTask *downloadTask = [islandRef writeToFile:localURL completion:^(NSURL *URL, NSError *error){ if (error != nil) { // Uh-oh, an error occurred! } else { // Local file URL for "images/island.jpg" is returned } }];
如果要主动管理下载,您可以使用 writeToFile:
方法并观察下载任务,而不是使用完成处理程序。如需了解详情,请参阅管理下载。
生成下载网址
如果您已经有了基于网址的下载基础架构,或者只需要一个网址用于共享,可通过对 Cloud Storage 引用调用 downloadURLWithCompletion:
方法来获取文件的下载网址。
Swift
// Create a reference to the file you want to download let starsRef = storageRef.child("images/stars.jpg") // Fetch the download URL starsRef.downloadURL { url, error in if let error = error { // Handle any errors } else { // Get the download URL for 'images/stars.jpg' } }
Objective-C
// Create a reference to the file you want to download FIRStorageReference *starsRef = [storageRef child:@"images/stars.jpg"]; // Fetch the download URL [starsRef downloadURLWithCompletion:^(NSURL *URL, NSError *error){ if (error != nil) { // Handle any errors } else { // Get the download URL for 'images/stars.jpg' } }];
通过 FirebaseUI 下载图片
FirebaseUI 提供简单、可定制且适合生产环境的原生移动绑定,以消除样板代码并促进遵循 Google 最佳实践。借助与 SDWebImage 的集成,您可以使用 FirebaseUI 快速轻松地下载、缓存和显示 Cloud Storage 中的图片。
首先,将 FirebaseUI 添加到您的 Podfile
文件:
pod 'FirebaseStorageUI'
然后,您可以直接将 Cloud Storage 中的图片加载到 UIImageView
:
Swift
// Reference to an image file in Firebase Storage let reference = storageRef.child("images/stars.jpg") // UIImageView in your ViewController let imageView: UIImageView = self.imageView // Placeholder image let placeholderImage = UIImage(named: "placeholder.jpg") // Load the image using SDWebImage imageView.sd_setImage(with: reference, placeholderImage: placeholderImage)
Objective-C
// Reference to an image file in Firebase Storage FIRStorageReference *reference = [storageRef child:@"images/stars.jpg"]; // UIImageView in your ViewController UIImageView *imageView = self.imageView; // Placeholder image UIImage *placeholderImage; // Load the image using SDWebImage [imageView sd_setImageWithStorageReference:reference placeholderImage:placeholderImage];
管理下载
除了启动下载,您还可以使用 pause
、resume
和 cancel
方法来暂停、恢复和取消下载。这些方法会引发您可以观察的 pause
、resume
和 cancel
事件。
Swift
// Start downloading a file let downloadTask = storageRef.child("images/mountains.jpg").write(toFile: localFile) // Pause the download downloadTask.pause() // Resume the download downloadTask.resume() // Cancel the download downloadTask.cancel()
Objective-C
// Start downloading a file FIRStorageDownloadTask *downloadTask = [[storageRef child:@"images/mountains.jpg"] writeToFile:localFile]; // Pause the download [downloadTask pause]; // Resume the download [downloadTask resume]; // Cancel the download [downloadTask cancel];
监控下载进度
您可以向 FIRStorageDownloadTask
附加观察者 (observer),以便监控下载的进度。添加观察者后会返回一个 FIRStorageHandle
,它可用于移除此观察者。
Swift
// Add a progress observer to a download task let observer = downloadTask.observe(.progress) { snapshot in // A progress event occurred }
Objective-C
// Add a progress observer to a download task FIRStorageHandle observer = [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { // A progress event occurred }];
这些观察者可以注册到一个 FIRStorageTaskStatus
事件:
FIRStorageTaskStatus 事件 | 典型用法 |
---|---|
FIRStorageTaskStatusResume |
此事件在任务开始或恢复下载时触发,且通常与 FIRStorageTaskStatusPause 事件结合使用。 |
FIRStorageTaskStatusProgress |
每次从 Cloud Storage 下载数据时,此事件都会触发,并可用于为下载进度指示器提供所需数据。 |
FIRStorageTaskStatusPause |
每次下载被暂停时,此事件都会触发,通常与 FIRStorageTaskStatusResume 事件结合使用。 |
FIRStorageTaskStatusSuccess |
此事件会在下载成功完成时触发。 |
FIRStorageTaskStatusFailure |
此事件会在下载失败时触发。请检查错误以确定失败原因。 |
当有事件发生时,系统将传回 FIRStorageTaskSnapshot
对象。此快照是事件发生时的任务视图,该视图不可改变。
此对象包含以下属性:
属性 | 类型 | 说明 |
---|---|---|
progress |
NSProgress |
包含下载进度的 NSProgress 对象。 |
error |
NSError |
下载期间发生的错误(如果有)。 |
metadata |
FIRStorageMetadata |
下载时为 nil 。 |
task |
FIRStorageDownloadTask |
快照所对应的任务,可用于管理任务(使用 pause 暂停、使用 resume 继续、使用 cancel 取消)。 |
reference |
FIRStorageReference |
此任务的来源引用。 |
您可以逐个移除观察者,也可以按状态移除或是全部移除。
Swift
// Create a task listener handle let observer = downloadTask.observe(.progress) { snapshot in // A progress event occurred } // Remove an individual observer downloadTask.removeObserver(withHandle: observer) // Remove all observers of a particular status downloadTask.removeAllObservers(for: .progress) // Remove all observers downloadTask.removeAllObservers()
Objective-C
// Create a task listener handle FIRStorageHandle observer = [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { // A progress event occurred }]; // Remove an individual observer [downloadTask removeObserverWithHandle:observer]; // Remove all observers of a particular status [downloadTask removeAllObserversForStatus:FIRStorageTaskStatusProgress]; // Remove all observers [downloadTask removeAllObservers];
为了防止内存泄露,所有观测器在发生 FIRStorageTaskStatusSuccess
或 FIRStorageTaskStatusFailure
后都会被移除。
处理错误
导致下载出错的原因有很多,包括文件不存在,或者用户不具备访问相应文件的权限。如需了解有关错误的详细信息,请参阅文档的处理错误部分。
完整示例
下面是下载到本地文件的完整示例(包含错误处理):
Swift
// Create a reference to the file we want to download let starsRef = storageRef.child("images/stars.jpg") // Start the download (in this case writing to a file) let downloadTask = storageRef.write(toFile: localURL) // Observe changes in status downloadTask.observe(.resume) { snapshot in // Download resumed, also fires when the download starts } downloadTask.observe(.pause) { snapshot in // Download paused } downloadTask.observe(.progress) { snapshot in // Download reported progress let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount) / Double(snapshot.progress!.totalUnitCount) } downloadTask.observe(.success) { snapshot in // Download completed successfully } // Errors only occur in the "Failure" case downloadTask.observe(.failure) { snapshot in guard let errorCode = (snapshot.error as? NSError)?.code else { return } guard let error = StorageErrorCode(rawValue: errorCode) else { return } switch (error) { case .objectNotFound: // File doesn't exist break case .unauthorized: // User doesn't have permission to access file break case .cancelled: // User cancelled the download break /* ... */ case .unknown: // Unknown error occurred, inspect the server response break default: // Another error occurred. This is a good place to retry the download. break } }
Objective-C
// Create a reference to the file we want to download FIRStorageReference *starsRef = [storageRef child:@"images/stars.jpg"]; // Start the download (in this case writing to a file) FIRStorageDownloadTask *downloadTask = [storageRef writeToFile:localURL]; // Observe changes in status [downloadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) { // Download resumed, also fires when the download starts }]; [downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { // Download paused }]; [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { // Download reported progress double percentComplete = 100.0 * (snapshot.progress.completedUnitCount) / (snapshot.progress.totalUnitCount); }]; [downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { // Download completed successfully }]; // Errors only occur in the "Failure" case [downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { if (snapshot.error != nil) { switch (snapshot.error.code) { case FIRStorageErrorCodeObjectNotFound: // File doesn't exist break; case FIRStorageErrorCodeUnauthorized: // User doesn't have permission to access file break; case FIRStorageErrorCodeCancelled: // User canceled the upload break; /* ... */ case FIRStorageErrorCodeUnknown: // Unknown error occurred, inspect the server response break; } } }];
对于存储在 Cloud Storage 中的文件,您还可以获取和更新元数据。