2012-06-22 62 views
2

我有一個使用XMPP與EJABBERD服務器的iPhone聊天應用程序,如果應用程序進入後臺(通過點擊主頁按鈕或缺少活動,然後屏幕變黑),設置爲正常運行,然後繼續在被帶到前臺時正確運行。iphone 4S在後臺經過一段時間後從XMPP服務器脫機?

當進入後臺並回到前臺時,該應用可以在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不再有效。 20分鐘左右後,iPad也會在XMPP服務器上快速脫機,而iPhone 4S則需要幾個小時才能脫機。也許在iPad和iPhone 4S之間發生不同的脫機方法?

我試着在XMPPStream.h中播放DEFAULT_KEEPALIVE_INTERVAL,如SO post中提到的那樣,目前爲止沒有成功。在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

我終於通過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  
}); 
} 
相關問題