2011-07-28 60 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