2010-01-07 62 views
2

我的iPhone应用支持使用CocoaAsyncSocket库的专有网络协议。当我的iPhone应用程序关闭时,我需要能够发送网络消息。发送消息的代码是从应用程序委托中调用的,但是在消息实际发布之前应用程序会关闭。有没有办法让应用程序保持足够长的时间以使消息熄灭?发送网络消息当iPhone应用程序被关闭

布鲁斯

+0

您是否可以阻止主线程,直到您知道网络消息已成功发送? – lucius 2010-01-07 21:37:54

回答

2

从苹果公司的文档不具体说明这一点,但感觉我环视Web和从个人的经验得到的是,你有大约4至5秒,用户点击Home键后在应用程序实际终止之前关闭您的应用程序。 iPhone OS正在控制这个功能,所以你不能阻止终止,让你的程序先完成。基本上当你的时间到了,你的程序就会被杀死。

有可能是另一种解决方案,但。首先我确认你的代码真的需要超过5秒钟才能运行。也许你可以让它运行,以响应按钮敲击,以及运行时间。如果超过5秒钟,您可能会遇到这个问题。

那么你可能会找到一个方法来触发一条消息从一个始终运行的服务器进行发送。您应该有足够的时间来触发远程操作,然后只要需要运行,该操作就可以进行。

或者你可以保存重要的信息就退出iPhone文件系统,并在下次有人开始应用,这理论上应该给你足够的时间发送该消息。

希望这会有所帮助!

2

我假设你已经从你的AppDelegate调用它:

- (void)applicationWillTerminate:(UIApplication *)application 

但是,正如你已经发现有不能保证它会被称为或将被允许完成。有可能会或可能不取决于你想要做什么工作的几个选项:

  • 如果您需要的服务器进行某种形式的清洁操作通过在客户端应用程序走了,然后你触发可以尝试监视服务器上的TCP套接字关闭并将其视为触发事件。但是如果你明确地需要用闭包发回数据,这可能不起作用。

  • 如果您发回的数据不是时间敏感的,那么您可以像大多数分析库一样执行操作并在客户端上缓存数据(以及uuid),然后尝试通过应用程序关闭发送它。如果通过,您可以清除缓存(或者在下次运行该应用程序时执行此操作)。如果没有,它会被保存下来,然后你可以在应用下一次运行时发送出去。在服务器上,您可以使用uuid来避免重复的请求。

  • 如果材料是对时间敏感的那么最好的办法是实行心跳和定期发送更新值到服务器。然后,当客户端应用程序的去世服务器超时心跳,并且可以使用最后收到的值作为数据的最终收盘点位。

在这两种情况下,如果您的自定义协议需要明确的关闭事件,那么你可能想在现实生活中的移动环境中使用它,事情必须要更加流畅和宽容失败的反思。

0

正如其他人已经指出的,没有办法可以绝对确定您可以发送该消息,但有办法提供帮助。正如肯注意到的,你在实践中会在“willTerminate”和强制终止之间花费几秒钟,所以通常有时间去做你所需要的。

你几乎肯定会碰到一个问题,就是使用CocoaAsyncSocket。当你得到“willTerminate”消息时,你处于主线程的最后一个运行循环中。所以如果你阻塞主线程,并且CocoaAsyncSocket在主线程上运行,它将永远不会被处理。我记得,CocoaAsyncSocket实际上不会发送所有数据,直到下一个事件循环。

一种方法,因此要保持自己抽的事件循环:

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
    // ...Send your message with CocoaAsyncSocket... 

    while (! ...test to see if it sent...) 
    { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    } 
} 

我也看了一下把这个工作到后台线程,让主线程终止,在理论上让我们去回到Springboard,同时继续运行几秒钟。我不清楚这是否可以正确使用NSThread(它是分离的)。使用POSIX线程(默认情况下可以连接)可能会起作用,但可能会绕过后台线程的任何优势。无论如何,这是有用的东西。在我的应用程序中,我们使用“发布下次发布”的方法,因为它总是有效的(即使你崩溃了)。

相关问题