我有使用firebase for database的应用程序,我希望在用户终止应用时清除名为current_venue
的特定用户字段,为此我使用AppDelegate
方法applicationWillTerminate
并且&# 39;当我杀死应用程序时,实际上是在调用,但不是完全。
以下是AppDelegate
中的代码:
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
WebServiceAPI.checkOutVenue()
}
另一种方法是:
static func checkOutVenue() {
WebServiceAPI.sharedInstance.current_venue = ""
if WebServiceAPI.sharedInstance.user == nil {
return
}
let user = WebServiceAPI.sharedInstance.user!
let ref = FIRDatabase.database().reference()
ref.child("Clients").child(user.uid).child("current_venue").setValue("") { (err, venueIdRef) in
if err == nil {
WebServiceAPI.sharedInstance.current_venue = ""
}
}
}
我尝试调试它,如下图所示:
当我杀死app断点1和2正在调用但它从未到达断点3时。
我阅读了以下文档:
https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate
其中说:
您执行此方法大约需要五秒钟才能执行任何任务并返回。如果方法在时间到期之前没有返回,系统可能会完全终止该进程。
实际上它不需要花费超过5秒的时间来清除火场中的那个场地。
当我打开应用程序时,相同的代码工作正常。
所以我的代码工作正常,但是当我杀死应用程序时,我会遗漏一些东西。
感谢您的帮助。
答案 0 :(得分:3)
确保在用户断开连接时清除数据的更好方法是使用var forempty = document.getElementById("cte");
while( forempty.firstChild ){
forempty.removeChild(forempty.firstChild);
}
document.getElementById("cte").value = something;
//or
document.getElementById("cte").textContent = something;
处理程序。 Firebase documentation explains them,但这是一个如何使用它的简单示例:
onDisconnect
执行此代码时,将指令发送到服务器以在客户端断开连接时删除节点。这意味着它将始终运行,即使客户端(甚至手机)崩溃并且您的客户端代码永远不会有机会执行。
答案 1 :(得分:2)
在applicationWillTerminat 中执行异步任务不是最佳方法 ,因为您有5秒的时间来确保异步任务取决于强度互联网连接应该完成执行(对于普通用户而言,这可能需要不到5秒,这可能需要更多),否则该过程将被杀死。
正如我在评论部分提到的那样,即使你得到了这项工作,也有另外一个你没想过的案例:
如果用户首先将应用切换为后台,则在尝试终止应用后,将不会调用applicationWillTerminate。
你正在尝试理论上不可能的事情
尝试考虑这样的事情:
func applicationDidEnterBackground(_ application: UIApplication) {
WebServiceAPI.checkOutVenue()
}