【发布时间】:2022-11-14 17:13:35
【问题描述】:
有一个handlerDoneTapped() 函数,当单击Done 按钮时应用该函数,它将字段中的数据(包括图像和path)保存到Firestore 中。
func handleDoneTapped() {
self.viewModel.handleDoneTapped()
self.uploadImage() // For Storage and path to it
self.dismiss()
}
在handleDoneTapped() 函数内部,还有另一个uploadImage() 函数将图像上传到Storage 并将path 保存到pic 参数。
@ObservedObject var viewModel = NewItemView()
func uploadImage() {
let storage = Storage.storage().reference()
let picData: Data = pickedImages[0].jpegData(compressionQuality: 0.5)!
let path = "itemImages/\(UUID().uuidString).jpg"
let ref = storage.child(path)
let metadata = StorageMetadata()
metadata.contentType = "image/jpg"
_ = ref.putData(picData, metadata: metadata, completion: { (storageMetaData, error) in
if error != nil {
print(error?.localizedDescription as Any)
return
} else {
self.viewModel.singleitem.pic = path // I specify the path to the pic parameter [singleitem - also from NewItemView()]
self.viewModel.updateOrAddItem() // I make changes through the function from NewItemView()
}
})
}
@ObservedObject var viewModel = NewItemView() - 让我们参考 Firestore 参数来保存数据。
class NewItemView: ObservableObject {
@Published var singleitem: SingleItem
init(singleitem: SingleItem = SingleItem(title: "", author: "", description: "", pic: "")) {
self.singleitem = singleitem
self.$singleitem
.dropFirst()
.sink { [weak self] singleitem in
self?.modified = true
}
.store(in: &self.cancellables)
}
private var db = Firestore.firestore()
private func addItem(_ singleitem: SingleItem) {
do {
var addedItem = singleitem
addedItem.userId = Auth.auth().currentUser?.uid
_ = try db.collection("items").addDocument(from: addedItem)
}
catch {
print(error)
}
}
private func updateItem(_ singleitem: SingleItem) {
if let documentID = singleitem.id {
do {
try db.collection("items").document(documentID).setData(from: singleitem)
}
catch {
print(error)
}
}
}
public func updateOrAddItem() { // This func I call inside uploadImage() to update path for pic parameter
// (bc without that pic: "" -is empty inside Firestore)
if singleitem.id != nil {
self.updateItem(self.singleitem)
}
else {
addItem(singleitem)
}
}
func handleDoneTapped() { // This func I call when I tapped Done button to add or update item
self.updateOrAddItem()
}
最后 SingleItem 结构与所有 vars:
struct SingleItem: Identifiable, FirestoreProtocol {
@DocumentID var id : String?
@ServerTimestamp var createdTime: Timestamp?
var title : String
var author : String
var description : String
var userId : String?
var pic : String
}
enum CodingKeys: String, CodingKey {
case id
case title
case author
case description = ""
case pic
}
所以,我知道我调用了两次self.viewModel.updateOrAddItem() 函数,但是如果我不在uploadImage() 中使用这个函数,那么文档会在没有pic 参数的情况下保存,其中包含path 到图像中贮存。
但是当我在uplaodImage() 中使用这个函数时,两个相同的文档被保存到Firestore 中,不同之处在于其中一个包含path 到pic 字段中的图像。
总的来说,我有点困惑,我尝试使用这些函数更改输入数据的参数,以过滤掉不包含必要信息的重复文档,但一切都导致文档保存时没有一个pic字段(path里面是空的),或者两个,其中一个需要,另一个不需要。
也许有人会看到我在哪里犯了错误。此外,我只提供了与问题相关的必要代码,部分代码以及可能缺少括号。
【问题讨论】:
-
如果视图被重绘,这个`@ObservedObject var viewModel = NewItemView()` 有可能创建新的视图模型实例。视图模型应该从超级视图注入或来自环境。您的
uploadImage代码也属于您的视图模型或模型。 -
你有没有试过使用
@StateObject var viewModel = NewItemView() -
@workingdogsupportUkraine 是的,没有任何变化。
-
您能否添加您的 Firebase 控制台的屏幕截图,显示两个不正确的文档。我假设如果您有两个,那么它们具有不同的 ID,对吗?
标签: ios xcode swiftui firebase-storage