1

我有一个使用firebase作为数据库的应用程序,我想清除current_venue用户杀死应用程序时调用的特定用户字段,为此我正在使用AppDelegate方法applicationWillTerminate,它实际上是在我杀死应用程序时调用但不完全。

下面是我的代码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 = ""
        }
    }
}

我尝试调试它,如下图所示:

在此处输入图像描述

当我杀死应用程序断点 1 和 2 时正在调用,但它从未到达断点 3。

我从以下位置阅读了文档:

https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate

其中说:

您对此方法的实现大约有五秒钟的时间来执行任何任务并返回。如果该方法在时间到期之前没有返回,系统可能会完全终止该进程。

实际上,从火力基地清除该领域的时间不超过 5 秒。

当我打开应用程序时,相同的代码工作正常。

所以我的代码工作正常,但是当我杀死应用程序时我缺少一些东西。

谢谢你的帮助。

4

2 回答 2

4

确保在用户断开连接时清理数据的更好方法是使用onDisconnect处理程序。Firebase 文档对它们进行了解释,但这里有一个简单的示例说明如何使用它:

ref.child("Clients")
   .child(user.uid)
   .child("current_venue")
   .onDisconnectRemoveValue()

当这段代码执行时,当客户端断开连接时,指令被发送到服务器以移除节点。这意味着它将始终运行,即使客户端(甚至电话)崩溃并且您的客户端代码永远没有机会执行。

于 2017-04-20T13:47:14.287 回答
2

在 applicationWillTerminat中有一个异步任务不是最好的方法,因为你有 5 秒的时间来确保一个取决于互联网连接强度的异步任务应该完成它的执行(对你来说,对于普通用户来说,这可能需要不到 5 秒这可能需要更多时间),否则进程将被终止。

正如我在评论部分提到的那样,即使您完成了这项工作,您也没有考虑过另一种情况:

如果用户首先将应用程序切换到后台,并且在此尝试终止应用程序之后,将不会调用 applicationWillTerminate。

你正在尝试一些理论上不可能的事情

试着想想这样的事情:

func applicationDidEnterBackground(_ application: UIApplication) {

     WebServiceAPI.checkOutVenue()
}
于 2017-04-20T10:11:45.033 回答