首页 > 解决方案 > 如何在一个 vc 中设置计时器并在另一个 vc 中触发它

问题描述

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

在我创建文档的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 正在存储创建的文档的详细信息,您无法获取尚未创建的文档的详细信息,所以我将它放在另一个 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 中的计时器触发。

标签: swifttimernstimerdispatch-asyncdispatchertimer

解决方案


在做了一些研究和阅读之后,我认为最好使用 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()加载的事件只是未过期的事件。希望这可以对将来遇到同样问题的人有所启发。


推荐阅读