我有一个使用XMPP的iPhone聊天应用程序和EJABBERD服务器,如果应用程序进入后台(通过点击主页按钮或缺少活动,然后屏幕变黑),设置为正常运行,然后继续在被带到前台时正常运作。
该应用程序在进入后台并回到前台时可在iPad上正常工作,但当我在iPhone 4S上运行该应用程序时,应用程序进入后台大约一小时后,该应用程序将从XMPP服务器。然后当iPhone 4S回到前台时,应用程序不再连接到XMPP服务器。相比之下,在iPad上,该应用程序已在后台运行了一天以上,并且仍然在线使用XMPP服务器。
我看到了这个SO post,但由于应用程序已经在我的iPad上运行了一天以上,并且iPad上的应用程序仍然在线使用XMPP服务器,我不认为这就是问题。
1) Is this because the iPhone 4S goes into Airplane mode after some time?
2) If the answer to 1) is yes, is there a way for the app to programmatically stop the iPhone 4S from going into Airplane mode?
3) Or is something else going on?
更新1 -
有趣的是,iPad可以在XMPP服务器上脱机,但是当iPad上的应用程序被带到前台时,XMPP可以正常工作。但是如果iPhone 4S上的应用程序在XMPP服务器上脱机,那么当iPhone 4S上的应用程序被带到前台时,XMPP将不再有效。此外,iPad在XMPP服务器上快速脱机,大约20分钟后,而iPhone 4S需要几个小时才能脱机。也许在iPad和iPhone 4S之间出现了不同的离线方式?
我已经尝试过玩这个SO post中提到的XMPPStream.h中的DEFAULT_KEEPALIVE_INTERVAL,但到目前为止没有成功。在XXMPStream.h中,我有代码:
#if TARGET_OS_IPHONE
#define MIN_KEEPALIVE_INTERVAL 20.0 // 20 Seconds
#define DEFAULT_KEEPALIVE_INTERVAL 120.0 // 2 Minutes
#else
#define MIN_KEEPALIVE_INTERVAL 10.0 // 10 Seconds
#define DEFAULT_KEEPALIVE_INTERVAL 300.0 // 5 Minutes
#endif
更新2 -
另一个奇怪的是,当应用程序在iPhone 4的后台,如果iPad上的应用程序想要与iPhone 4聊天,iPad会向iPhone 4发送推送通知。此推送通知带来iPhone 4上的应用程序到达前台,iPhone 4尝试重新连接到EJABBERD服务器,但iPhone 4无法再重新连接。
更新3 -
iPad只有Wifi,而iPhone 4有Wifi和4G蜂窝连接。所以我想也许这就是区别。因此我将iPhone 4置于飞行模式,然后与Wifi连接,因此iPhone 4仅使用Wifi。但是2-3小时后,iPhone 4再次与EJABBERD服务器一起脱机。
答案 0 :(得分:0)
我终于通过此SO post找到了解决问题的方法。即使iPhone 4从EJABBERD服务器脱机,当应用程序到达前台时,应用程序可以重新连接到EJABBERD服务器,而之前的应用程序无法重新连接。
具体来说我使用了代码
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication* app = [UIApplication sharedApplication];
// it's better to move "dispatch_block_t expirationHandler"
// into your headerfile and initialize the code somewhere else
// i.e.
// - (void)applicationDidFinishLaunching:(UIApplication *)application {
//
// expirationHandler = ^{ ... } }
// because your app may crash if you initialize expirationHandler twice.
dispatch_block_t expirationHandler;
expirationHandler = ^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
};
bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// inform others to stop tasks, if you like
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyApplicationEntersBackground" object:self];
// do your background work here
});
}