2013-08-03 28 views
1

我注意到在我的應用程序,當應用程序進入後臺時加載導致錯誤,如「超時」或「主機名稱未找到」。NSURLConnection最佳做法當進入背景

這是由於不允許連接長時間在後臺運行的過程。

但是那種錯誤信息會導致用戶體驗不好。那麼我應該怎麼做才能取消交易?我應該取消所有連接嗎?我試圖在SO中搜索Q & A,但找不到答案。

有關更多信息,我的應用程序使用NSURLConnectionDelegate方法。我有一個商店單身人士管理與我的服務器的所有連接。 NSURLConnection也是在自定義對象中調用和管理的。

我試着在applicationDidEnterBackground中只是[連接取消]:但是這會導致UI被破壞,因爲我加載數據到UITableViewCell等。任何人都可以指出這個例子來解決這類問題嗎?

更新的代碼:

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
__block UIBackgroundTaskIdentifier backgroundTask; backgroundTask = 
[application  beginBackgroundTaskWithExpirationHandler:^{ 
[application endBackgroundTask:backgroundTask]; 
backgroundTask = UIBackgroundTaskInvalid; }]; } 

    } 

可我只是把這個代碼中的appDelegate?這樣做的缺點是將beginBackgroundTaskWithExpirationHandler放在我希望在任務完成後繼續在後臺和endBackgroundTask中運行的任務之前?我的代碼有一個直接處理NSURLConnection的對象。

+1

難道你的意思'[連接取消]'? – Peres

+0

是的,這是正確的。[連接取消]不會停止。 –

回答

2

在進入後臺後,您可以繼續運行NSURLConnection一段時間。蘋果公司並沒有公佈準確的時間段,但它只有10分鐘。有關如何使用beginBackgroundTaskWithExpirationHandler:請求更多時間來完成下載的詳細信息,請參閱Executing a Finite-Length Task in the Background

在大多數情況下,您不應主動取消下載。您應該等到系統到期後再處理該錯誤。如果下載是短暫的,沒有理由取消它(在大多數情況下,有關連接的最貴的東西是設置它擺在首位)。如果它是一個非常長的下載,那麼如果用戶不在後臺進行操作,用戶會感到惱火。 (這是假設你正在下載東西,因爲用戶要求它。)

+0

感謝您的建議。我的應用程序將處理該applicationDidEnterBackground委託下載的東西。所以另一個對象。我可以只調用__block UIBackgroundTaskIdentifier backgroundTask; backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^ {[application endBackgroundTask:backgroundTask]; backgroundTask = UIBackgroundTaskInvalid; }]; }?當應用程序進入後臺10分鐘後,handlerBlock將被調用。因此,它將終止BackgroundTaks。這一個看起來更容易,但我不是如果它浪費很多資源 –

0

首先,最好是對應用程序委託此調用,這樣在NavigationController視圖可以關閉。其次,標記後臺處理的年初beginBackgroundTaskWithExpirationHandler:endBackgroundTask:這樣結束吧:

.H:

UIBackgroundTaskIdentifier bgTask; 

.M:

- (void)sendPhoto:(UIImage *)image 
{ 
    UIApplication *app = [UIApplication sharedApplication]; 

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
    }]; 


    NSLog(@"Sending picture..."); 

    // Init async NSURLConnection 

    // .... 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

    NSLog(@"Picture sent."); 

    UIApplication *app = [UIApplication sharedApplication]; 

    if (bgTask != UIBackgroundTaskInvalid) { 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
    } 
} 

還記得一件事其重要:

You have 10 minutes before iOS terminates your app. You can check this time with [app backgroundTimeRemaining]

+0

感謝您的答案。但我不太清楚。你的意思是我應該把這種代碼放在控制器或appDelegate中? –

+0

或者我可以把這段代碼放在appDelegate中 - (void)applicationDidEnterBackground:(UIApplication *)application {__block UIBackgroundTaskIdentifier backgroundTask; backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^ {application endBackgroundTask:backgroundTask]; [0124] backgroundTask = UIBackgroundTaskInvalid; }]; } –

+0

是的,你可以把這段代碼放入你的應用程序中,這將是一件好事! –