如何在一个 vc 中设置计时器并在另一个 vc 中触发它

问题描述

我的目标是在创建 firestore 文档时在一个 vc 中设置一个计时器,并在计时器到时时在另一个 vc 中触发它以删除 firestore 文档。

在我创建文档的 vc 中,我在用于在 firestore 中创建文档的按钮中有这段代码

db.collection("school_users/\(user?.uid)/events").addDocument(data: ["event_name": nameTextField.text,"event_date": dateTextField.text,"event_cost": costTextField.text,"for_grades": gradesTextField.text,"school_id": schoolIDTextF.text,"time_created": Date()]) { (error) in
                if error != nil {
                    self.showError("There was an error trying to add user data to the system.")
                } else {
                    self.setTimerForEventDeletion()
                    self.dismiss(animated: true,completion: nil)
                }
            }

setTimerForEventDeletion() 函数包含以下内容

  func setTimerForEventDeletion() {
    let date = dateTextField.text!
   let datetoDelete = formatter.date(from: date)!
    let timer = Timer(fireAt: datetoDelete,interval: 0,target: self,selector: #selector(callDeleteEventFunction),userInfo: nil,repeats: false)
    
}

日期格式也正确,我已经完成了所有设置。对于 objc 方法,我从该函数中的不同 vc(将解释)调用一个函数

 @objc func callDeleteEventFunction() {
    otherVC.deleteEventAtEventTime()
}

我从另一个vc调用这个函数的原因是因为另一个vc正在存储创建的文档的详细信息,您无法获取尚未创建的文档的详细信息,所以我在另一个风险投资。函数看起来像这样...

@objc func deleteEventAtEventTime() {
    db.document("school_users/\(user?.uid)/events/\(selectedEventDocID!)").delete { (error) in
        if let error = error {
            print("There was an error deleting the doc: \(error)")
        } else {
            print("Doc deleted!")
        }
    }

}

现在在发布这个问题之前,我通过在存储文档详细信息的同一个 vc 中触发计时器来测试它并且它工作,但是当我退出该 vc 时,单元格被删除并且 tableview 缩小,基本上是应用程序出现故障,并最终在我单击具有不同详细信息的另一个单元格时崩溃。

所以我希望能够在一个 vc 中创建文档时设置计时器,并在删除日期到达时在另一个 vc 中触发计时器。

解决方法

在进行了一些研究和阅读之后,我认为最好使用 Googe Cloud Functions 来执行自动删除数据库和我的应用中的 Firestore 文档的任务。

在做了更多的研究之后,我意识到至少现在没有必要经历这个。我将提供一个非常简单的解决方法,该解决方法需要大约 20 分钟的时间才能弄清楚,并避免我必须学习 Node 才能使用 Cloud Functions。

所以我想要完成的是能够在文档自动过期时删除它们,我用几块代码就完成了。

首先,我声明了 2 个变量来帮助格式化。

let rightNow = Date()
let formatter = DateFormatter()

这些将有助于我将要展示的下一个功能。

  func setupDate(completion: @escaping ((String?) -> ())) {
    formatter.dateFormat = "EEEE,MMMM d yyyy,h:mm a"
   let dateToString = formatter.string(from: rightNow)
    completion(dateToString)
}

这个函数给了我一个 String 的日期,所以我可以把它放在我的查询函数中,我也会显示它。我使用 nsdateformatter.com 来获取我在文本字段中的确切格式,我建议使用该站点获取 Date() 与格式相关的代码。

下一个功能基本上完成了交易,这也是一切正常的原因。

func deleteExpiredCreatedEvents() {
    setupDate { (dateforexpiry) in
            self.db.collection(Constants.Firebase.schoolCollectionName).whereField("expiresAt",isLessThanOrEqualTo: dateforexpiry!).addSnapshotListener { (querySnapshot,error) in
                if error != nil {
                    print("Error fetching docs/User deleted account.")
                } else {
                    for document in querySnapshot!.documents {
                        let documentident = document.documentID
                        let docalgoliaid = document.get("algoliaObjectID") as! String
                        
                        deleteIndex.deleteObject(withID: ObjectID(rawValue: docalgoliaid)) { (result) in
                            if case .success(let response) = result {
                                print("Record Deleted!: \(response.wrapped)")
                            }
                        }

                        self.db.document("school_users/\(self.user?.uid)/events/\(documentident)").delete { (err) in
                            if err != nil {
                                print("Errr")
                            } else {
                                print("No errs")
                                self.tableView.reloadData()
                            }
                        }
                    }
                }
            }
    }
}

然后我在所需 vc 的 viewDidLoad() 中调用此函数,加载的事件只是未过期的事件。希望这可以为将来遇到相同问题的人提供一些启发。