2011-07-28 58 views
6

我需要實現在後臺發佈一些數據到網絡服務器。只是爲了澄清,「在後臺」中,我不是指使用類似AsyncTaskASIHTTPRequest[request startAsynchronous]方法顯示旋轉圖標並將數據發佈到Web服務的正常方式。我需要維護一個線程可以異步開始處理並在用戶在應用程序中工作時發佈到Web服務的數據隊列。後臺網絡調用 - iOS

我正在尋找一些幫助設計這樣的隊列,特別是在一些邊緣情況下,如用戶接收呼叫,在帖子發生時註銷應用程序,用戶離開應用程序以轉到另一個而帖子正在發生等。你將如何處理這些案件?有沒有任何源代碼可以推薦這樣做?

謝謝,
Teja。

+1

你應該[大中央調度]讀了(http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html) – bshirley

回答

3

我在我自己的工作中使用NSOperationQueue最近開始,用於控制後臺網絡請求。 NSOperation處理背景(或前景,如果UI更新需要時)線程上的異步運行任務(如網絡操作)所需的大部分樣板代碼。

它還允許跨隊列的依賴關係;例如,我在我的應用程序中使用兩個隊列:

第一個時間表圖像下載,在一個時間的最大併發數爲2,在後臺。每個圖像下載都有一個相應的完成處理程序(作爲NSBlockOperation),這取決於圖像下載完成情況。這些操作位於[NSOperationQueue mainQueue],它在主線程上運行,允許它們更新UI(具體而言,相應的UIImageView)。

請注意,NSOperationNSOperationQueue不僅適用於網絡請求,也適用於可以分爲原子任務並且同時調度的任何操作。

Here是蘋果公司關於該主題的介紹文檔。

2

自己實現了類似的東西,我會建議使用服務而不是線程來進行網絡調用。這樣即使你的活動被殺死,你也確定你的網絡電話會被執行。

然後執行隊列中,我建議你看看到IntentService(http://developer.android.com/reference/android/app/IntentService.html)

從文檔:

IntentService是服務的基類,用於按需處理異步請求(表示爲Intents) 請求。客戶通過startService(Intent)調用發送請求 ;該服務根據需要啓動, 依次使用工作線程處理每個Intent,並在其用完時停止其自身 。

此「工作隊列處理器」模式通常用於從應用程序的主線程卸載任務 。 IntentService類存在到 簡化了這種模式並照顧了機制。要使用它, 擴展IntentService並實現onHandleIntent(意圖)。 IntentService將收到意圖,啓動工作線程,並且 根據需要停止該服務。

所有請求都在單個工作線程上處理 - 它們可能需要多長時間(並且不會阻止應用程序的主循環),但是一次只能處理一個請求。

如果你的應用是足夠的,你可以使用sendBroadCast()來分享自己的活動和IntentService之間的信息和通知簡單

+1

同意,但我需要在iOS,Blackberry和Android上實現這個功能,所以我希望能夠避免服務...... –

+0

好的我明白了你的觀點,我看到你的帖子標題只有iOS,直到我提交了答案。 –

+1

Android應用程序使用Java編寫,而iOS應用程序使用Objective-C編寫。我認爲你不能使用相同的代碼。 (我知道,NDK包在Android中支持本地代碼)。這可能是最好的3個不同的問題。 – CrackerJack9

0

創建封裝線程單身:

在你的對象的初始化:

[NSThread detachNewThreadSelector:@selector(mainPosterThread) toTarget:self withObject:nil]; 

- (void)mainDownloaderThread 
{ 

    if([NSThread respondsToSelector:@selector(setThreadPriority:)]) 
    { 
     [NSThread setThreadPriority:0.1]; 
    } 
    NSString *urlToDownload = nil; 
    while(shouldRun) 
    { 
     // Take next data to post in a queue (lastObject of a NSArray for example) 
     if(nextDataToPost) 
     { 
      // Post 
     } 
     else 
     { 
      // Sleep for some time. 
     } 
    } 
} 

您也可以停止/啓動線程的方法,而應用去一個背景/前景多任務支持的設備。如果不支持多任務處理,請在停止時將發佈的數據保存在隊列中(如果不是太長),並在啓動時恢復它們。最大的挑戰是管理能夠取消當前上傳,而應用程序將結束。

0

這是一個我在寫每個新應用程序時都會完善的問題。基本上我想要的網絡功能是異步的,並且是使用本地功能編寫的。如果您有興趣,我很樂意向您展示一些此代碼。

首先,我建議您使用委託在主線程上異步執行所有網絡調用而不是同步。這種方式序列化/同步/併發不是問題。由於類是網絡委託,我只是發送一個類到新連接有一個新的委託實例。

[[NSURLConnection alloc] initWithRequest:request delegate:del] autorelease]; 

e.g. 
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data