ios - 下载多个图像后超出 Cloud Storage for Firebase 带宽配额 - 最佳做法是什么?
问题描述
我正在构建一个 iOS 应用程序,其数据存储在 Firestore 中,相关图像存储在 Cloud Storage for Firebase 中。从本质上讲,我的应用程序的起始屏幕是一个滚动的卡片列表,这些卡片代表来自我的 Firestore 集合之一的文档和关联的图像(从 Cloud Storage 中提取,使用文档标题匹配)。
为了生成起始滚动视图数据,每次打开我的应用程序时,我都会调用 Firestore 和 Cloud Storage 来填充我的本地结构并检索图像(其中大约 10 个,每个 600 像素 x 400 像素,大小在 300-500 KB 之间)。
我目前正在使用免费的 Spark 计划。我的 Firestore 配额很好,但昨天,我在模拟器中测试了该应用程序(可能运行了大约 60 次?)并且超过了 Cloud Storage 调用的 1 GB 带宽限制。我认为这是因为我正在下载大量图像而不是将它们存储在本地(因为每次运行应用程序时我都会再次下载它们?)。
以下是每次打开应用程序以获取所有数据和相关图像时运行的代码:
// StoryRepository.swift
import Foundation
import FirebaseFirestore
import FirebaseStorage
import FirebaseFirestoreSwift
class StoryRepository: ObservableObject { // listen to any updates
let db = Firestore.firestore()
let storage = Storage.storage()
@Published var stories = [Story]() // Story is a local struct with vars for title, previewImage (the associated card image I get from Cloud Storage), and other data in Firestore.
init() {
loadStoryCardData()
}
func loadStoryCardData() {
db.collection("stories").addSnapshotListener{ (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}
// create Cloud Storage reference
let storageRef = self.storage.reference()
// each document represents a story. get the title of that story, and then fetch the image from Cloud Storage that has the same filename as that title.
documents.forEach { document in
guard let title = document["title"] as? String else {
print("Could not read story title.")
return
}
let primaryImageRef = storageRef.child("storyCardPrimaryImages/" + title + ".jpg")
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
primaryImageRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print("Error fetching primary image: \(error)")
return
} else {
if let image = UIImage(data: data!) {
self.stories.append(Story(title: title, previewImage: image, data: document.data())!)
}
}
}
}
}
}
}
我只是想知道如何优化这个,因为当我发布这个应用程序并获得用户时,我可以想象我的带宽会去哪里。我是否应该将本地结构和图像存储在 iOS FileManager 中,以便在应用程序首次运行时只下载一次?如果 Firestore 或 Cloud Storage 中的任何内容发生变化,我将如何更新本地数据?
我曾考虑以较小的尺寸存储图像,但我真的需要它们在我的应用程序中为 600 像素 x 400 像素。如果可能的话,我更愿意继续使用免费的 Spark 计划。老实说,我只是有点吃惊,因为我在测试时已经遇到了配额限制——当只有我在运行应用程序时。总的来说,我有点不知所措——任何建议都会非常非常感激。
解决方案
我是否应该将本地结构和图像存储在 iOS FileManager 中,以便在应用程序首次运行时只下载一次?
使用这样的本地缓存绝对是减少总带宽使用的一种好方法。
如果 Firestore 或 Cloud Storage 中的任何内容发生变化,我将如何更新本地数据?
那将由你来设计。通常,执行此操作的一种方法是让您的进程更新存储中的对象,同时更新有关图像的一些元数据,并将其存储在 Firestore 中。您的应用可以查询 Firestore 以获取更改,然后在再次下载之前检查您本地缓存的文件是否是最新的。
我曾考虑以较小的尺寸存储图像,但我真的需要它们在我的应用程序中为 600 像素 x 400 像素。
您可以随时增加 JPG 压缩量,这也会降低图像质量。这是一个权衡,您必须根据自己的喜好进行试验。
推荐阅读
- python - xarray 创建与另一个文件具有相同纬度/经度网格的新数据集
- ios - 即使在#import "AIRGoogleMapOverlay.h" 之后在 AIRGoogleMapOverlayManager 中使用未声明的标识符 'AIRGoogleMapOverlay'
- javascript - 如何在 node.js 中重新启动程序
- java - 主机 IP 绑定失败
- c++ - 无法从模板基类导入 typedef
- c# - 通过 REST Api 查询 Twilio 调试器日志
- python - 如何以块的形式旋转现有数据框?
- javascript - 无法使用ajax读取未定义的属性'0'来获取json数据
- ios - 在 iOS 设备上偶然没有收到推送消息
- r - 根据条件捕捉栅格上的点