iphone 4S在后台播放一段时间后从XMPP服务器脱机?

时间:2012-06-22 16:26:18

标签: timeout xmpp background-process ejabberd iphone-4

我有一个使用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服务器一起脱机。

1 个答案:

答案 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     
}); 
}