iphone基于网络的客户端开发技巧——后台上传
2012-03-12 23:31
381 查看
from: http://blog.sina.com.cn/s/blog_4cd8dd130100t5cm.html
这里说的后台上传当然不是真的后台上传,只是在开启程序的情况下不影响操作的上传。
基本的思想就是开启一个线程,不断的处理上传操作。这里用队列比较方便一些。
主要做以下几步:
第一步:实现一个自定义类,继承NSObject
//添加到队列
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:_dic];
[self.operationQueue addOperation:theOp];
[theOp release];
//更新UI
}
- (void)reStartOperation:(NSDictionary *)_dic
{
//从userdefaults读取数据,并添加到队列
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int i = (int)[arr indexOfObject:_dic];
if (i == NSNotFound) {
return;
}
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:i]];
[dic setValue:[NSNumber numberWithInt:0] forKey:@"state"];//0 等待上传 1 上传中 2 失败
[arr replaceObjectAtIndex:i withObject:dic];
[userDefault setValue:arr forKey:@"upload"];
[userDefault synchronize];
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:dic];
[self.operationQueue addOperation:theOp];
[theOp release];
//更新UI
}
- (void)myTaskMethod:(id)_obj
{
//实现上传方法
//成功调用
[self performSelectorOnMainThread:@selector(taskMethodDidFinish:) withObject:nil waitUntilDone:YES];
//失败调用
[self performSelectorOnMainThread:@selector(taskMethodDidFailed:) withObject:nil waitUntilDone:YES];
}
- (void)taskMethodDidFailed:(id)_obj
{
//失败的任务更改状态之后保存
NSDictionary *tdic = [_obj retain];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];
[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int _index = (int)[arr indexOfObject:dic];
if (_index != NSNotFound) {
NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:_index]];
[tmp setValue:[NSNumber numberWithInt:2] forKey:@"state"];//0 等待上传 1 上传中 2 失败
[arr replaceObjectAtIndex:_index withObject:tmp];
}
[userDefault setObject:arr forKey:@"upload"];
[arr release];
[userDefault synchronize];
//更新UI
}
- (void)taskMethodDidFinish:(id)_obj
{
//成功的任务从userdefaults中删除
NSDictionary *tdic = [_obj retain];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];
[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int _index = (int)[arr indexOfObject:dic];
if (_index != NSNotFound) {
[arr removeObjectAtIndex:_index];
}
[userDefault setObject:arr forKey:@"upload"];
[arr release];
[userDefault synchronize];
//更新UI
}
第二步:在appdelegate中初始化一个MinroadOperation对象,添加的时候用addOperation(),重新开始的时候用reStartOperation()。
第三步:在程序重新开启的时候启动队列。同时有一点不确认,就是从后台返回貌似队列会继续进行,也就是说进入后台的时候队列处在等待状态。
需要注意的几点:
1. NSInvocationOperation的cancel方法只是设置一个标识,在进入队列的时候判断是否为true,从而判断是否进行。如果想取消NSInvocationOperation,可以尝试继承它。
2.避免无限重试。
这里说的后台上传当然不是真的后台上传,只是在开启程序的情况下不影响操作的上传。
基本的思想就是开启一个线程,不断的处理上传操作。这里用队列比较方便一些。
主要做以下几步:
第一步:实现一个自定义类,继承NSObject
@interface MinroadOperation : NSObject { NSOperationQueue *operationQueue; } - (void)addOperation:(NSDictionary *)_dic; - (void)reStartOperation:(NSDictionary *)_dic; @property (retain,nonatomic) NSOperationQueue *operationQueue; @end
@implementation MinroadOperation @synthesize operationQueue; - (id)init { self = [super init]; if (self) { self.operationQueue = [[NSOperationQueue alloc] init]; [self.operationQueue setMaxConcurrentOperationCount:2];//设置同时进行的线程数量,建议为2。 } return self; }
- (void)addOperation:(NSDictionary *)_dic { //保存上传列表到nsuserdefaults NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; if ([userDefault valueForKey:@"upload"] == nil) { NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObject:_dic],@"upload",nil]; [userDefault registerDefaults:dic]; [userDefault synchronize]; } else { NSArray *array = [userDefault valueForKey:@"upload"]; NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array]; [arr addObject:_dic]; [userDefault setObject:arr forKey:@"upload"]; [arr release]; [userDefault synchronize]; }
//添加到队列
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:_dic];
[self.operationQueue addOperation:theOp];
[theOp release];
//更新UI
}
- (void)reStartOperation:(NSDictionary *)_dic
{
//从userdefaults读取数据,并添加到队列
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int i = (int)[arr indexOfObject:_dic];
if (i == NSNotFound) {
return;
}
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:i]];
[dic setValue:[NSNumber numberWithInt:0] forKey:@"state"];//0 等待上传 1 上传中 2 失败
[arr replaceObjectAtIndex:i withObject:dic];
[userDefault setValue:arr forKey:@"upload"];
[userDefault synchronize];
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:dic];
[self.operationQueue addOperation:theOp];
[theOp release];
//更新UI
}
- (void)myTaskMethod:(id)_obj
{
//实现上传方法
//成功调用
[self performSelectorOnMainThread:@selector(taskMethodDidFinish:) withObject:nil waitUntilDone:YES];
//失败调用
[self performSelectorOnMainThread:@selector(taskMethodDidFailed:) withObject:nil waitUntilDone:YES];
}
- (void)taskMethodDidFailed:(id)_obj
{
//失败的任务更改状态之后保存
NSDictionary *tdic = [_obj retain];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];
[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int _index = (int)[arr indexOfObject:dic];
if (_index != NSNotFound) {
NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithDictionary:[arr objectAtIndex:_index]];
[tmp setValue:[NSNumber numberWithInt:2] forKey:@"state"];//0 等待上传 1 上传中 2 失败
[arr replaceObjectAtIndex:_index withObject:tmp];
}
[userDefault setObject:arr forKey:@"upload"];
[arr release];
[userDefault synchronize];
//更新UI
}
- (void)taskMethodDidFinish:(id)_obj
{
//成功的任务从userdefaults中删除
NSDictionary *tdic = [_obj retain];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:tdic];
[dic setValue:[NSNumber numberWithInt:1] forKey:@"state"];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *array = [userDefault valueForKey:@"upload"];
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:array];
int _index = (int)[arr indexOfObject:dic];
if (_index != NSNotFound) {
[arr removeObjectAtIndex:_index];
}
[userDefault setObject:arr forKey:@"upload"];
[arr release];
[userDefault synchronize];
//更新UI
}
- (void)dealloc { [operationQueue release]; [super dealloc]; } @end
第二步:在appdelegate中初始化一个MinroadOperation对象,添加的时候用addOperation(),重新开始的时候用reStartOperation()。
第三步:在程序重新开启的时候启动队列。同时有一点不确认,就是从后台返回貌似队列会继续进行,也就是说进入后台的时候队列处在等待状态。
需要注意的几点:
1. NSInvocationOperation的cancel方法只是设置一个标识,在进入队列的时候判断是否为true,从而判断是否进行。如果想取消NSInvocationOperation,可以尝试继承它。
2.避免无限重试。
相关文章推荐
- 基于网络的客户端开发技巧——第七篇后台上传
- 基于网络的客户端开发技巧——第一篇
- 基于网络的客户端开发技巧——第二篇Webview及正则
- 基于网络的客户端开发技巧——第三篇上下拖动切换页面
- 基于网络的客户端开发技巧——第三篇上下拖动切换页面
- 基于网络的客户端开发技巧——第四篇多账号的处理与注重细节
- 基于网络的客户端开发技巧——第五篇透过现象看本质
- 仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(一)好友资料
- 基于Hadoop开发网络云盘系统客户端界面设计初稿
- 仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(二)修改密码
- 基于Hadoop开发网络云盘系统客户端界面设计初稿
- Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载
- iPhone开发技巧之网络篇(1)--- 解析XML
- iPhone开发技巧之网络篇(1)— 解析XML
- iPhone开发技巧之网络--- Web服务
- iPhone开发技巧之网络篇(1)— 解析XML A
- iPhone开发技巧之网络篇(2)--- Web服务
- iPhone开发技巧之网络篇(3)--- 使用NSOperation建立多任务网络连接
- iPhone开发技巧之网络篇(4)--- 确认网络环境 3G/WIFI
- 基于Hadoop开发网络云盘系统客户端界面设计初稿