ASIHttpRequest上传数据
ASIHttpRequest是一套强大、易用的第三方网络开发库。其中ASIFormDataRequest类用于POST上传数据,包括常见的文本、图片、视频等都可以通过该类进行操作。在使用ASIFormDataRequest前,首先需要手动引用ASIFormDataRequest头文件。下面通过示例进行介绍。
一、POST上传文本数据
1、AddViewController.h
1
2
3
4
5
6
7
8
9
10
|
#import "BaseViewController.h"
#import "ASIHTTPRequest.h"
#import "SBJson.h"
#import "ASIFormDataRequest.h"
@interface AddViewController : BaseViewController{
ASIHTTPRequest *ASIHTTPRequest_;
ASIFormDataRequest *ASIFormDataRequest_;
}
@end
|
2、AddViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
//保存数据
-(
void
)saveData{
NSLog(@
"保存数据"
);
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:@
"http://api.beauty-soft.net/lisvcat.php?m=post&a=PostContent&type=json&vkey=%@&u=%@"
,[self userKey],[self userName]]];
ASIFormDataRequest_ =[[ASIFormDataRequest alloc] initWithURL:url];
[ASIFormDataRequest_ setPostValue:contentTextView_.text forKey:@
"content"
];
[ASIFormDataRequest_ setPostValue:@
"Iphone客户端"
forKey:@
"topsource"
];
ASIFormDataRequest_.delegate=self;
[ASIFormDataRequest_ startSynchronous];
[ASIFormDataRequest_ release];
}
//异步请求上传结果
- (
void
)requestFinished:(ASIFormDataRequest *)requestForm{
NSString *string=[requestForm responseString];
NSMutableDictionary *_dic=[string JSONValue];
if
([[_dic objectForKey:@
"status"
] intValue]==1) {
[self.navigationController popToViewController:self animated:YES];
IndexViewController *indexView=[[IndexViewController alloc] init];
[indexView refresh];
[self.navigationController pushViewController:indexView animated:YES];
[indexView release];
}
else
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@
"发送失败"
message:@
"网络繁忙,发送失败,请稍后再试"
delegate:self cancelButtonTitle:@
"OK"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
|
二、上传图片
使用ASIFormDataRequest类上传图片是非常轻松的事,一般情况下服务器端都是使用multipart/form-data数据提交方式的(方便WEB上传),使用ASIFormDataRequest提交数据,只需要4个步骤。下面分别介绍。
1、初始化UIImagePickerController控件
UIImagePickerController控件是一个图片拾取器,支持向图片库或者摄像头中抓取图片。在上传数据前首先需要获得数据,所以该步骤是必须的。代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
|
//1、上传图片
-(
void
)uploadPoto{
NSLog(@
"上传图片"
);
imagePicker_ =[[UIImagePickerController alloc] init];
[imagePicker_ setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
imagePicker_.delegate=self;
//允许编辑
imagePicker_.allowsEditing=YES;
//以模态视图弹出
[self presentModalViewController:imagePicker_ animated:YES];
[imagePicker_ release];
}
|
如果你需要获取于摄像头的图片,只需要修改setSourceType属性值即可。
1
2
3
4
5
6
7
8
9
|
- (
void
)pickImageFromAlbum
{
imagePicker_ = [[UIImagePickerController alloc] init];
imagePicker_.delegate = self;
imagePicker_.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker_.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
imagePicker_.allowsEditing = YES;
[self presentModalViewController:imagePicker animated:YES];
}
|
2、处理选择图片
用户选择完成图片后,UIImagePickerController控件通过didFinishPickingImage委托返回选择的图片信息,原则上就可以执行ASIFormDataRequest上传了。但问题又来了,UIImagePickerController控件返回的图片是原始数据的,这意味着图片的质量非常大,如果原质量上传不仅耗费巨大的流量而且会让上传变得非常慢。所以通用的做法是将图片进行一定的比例压缩后再执行上传。在IOS中,要对图片进行压缩处理是非常方便的,只需要使用UIImage对象下的drawInRect:CGRectMake()方法即可。
总得来说,在didFinishPickingImage委托方法中需要做的工作如下:
1)对选择返回的图片进行压缩处理(根据需要可以生成若干个缩略图);
2)对压缩后的图片作为临时文件保存到用户沙箱目录下;
3)执行ASIFormDataRequest异步上传。
实现的代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//2、选择图片完成
- (
void
)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
NSLog(@
"editingInfo%@"
,editingInfo);
UIImage *images_= [editingInfo objectForKey:@
"UIImagePickerControllerOriginalImage"
];
if
(picker.sourceType == UIImagePickerControllerSourceTypeCamera)
{
//如果采自于摄像头(注意模拟器产生异常)
}
UIImage *bigImage = [UtilMethod imageWithImageSimple:images_ scaledToSize:CGSizeMake(440.0, 440.0)];
//保存重新取样后的图片到沙盒中
UtilMethod *utlMethod=[[UtilMethod alloc] init];
[utlMethod saveImage:bigImage WithName:@
"tmp.jpg"
];
[utlMethod release];
UIImage *Image_30 = [UtilMethod imageWithImageSimple:images_ scaledToSize:CGSizeMake(30.0, 30.0)];
UtilMethod *utlMethods=[[UtilMethod alloc] init];
[utlMethods saveImage:Image_30 WithName:@
"tmp_30.jpg"
];
[utlMethods release];
[acivity_ startAnimating];
[self dismissViewControllerAnimated:YES completion:^{
//模态对话框隐藏之后执行上传
[self uploadPotoSave];
}];
}
|
如上述代码所示,UTilMethod类是一个自定义的类,主封装了图片压缩、获取沙箱路径等常规操作。读者可点击此下载UTilMethod功能类。处理完图片后就可以uploadPotoSave方法中进行异步上传
3、异步上传
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//3、上传初始化
- (
void
)uploadPotoSave
{
UtilMethod *utlMethod=[[UtilMethod alloc] init];
NSString *documemnt=[utlMethod documentFolderPath];
NSString *stringImage=[NSString stringWithFormat:@
"%@%@"
,documemnt,@
"/tmp.jpg"
];
[utlMethod release];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@
"http://api.beauty-soft.net/lisvcat.php?m=post&a=uploadPic&type=json&vkey=%@&u=%@"
,[self userKey],[self userName]]];
ASIFormDataRequest_=[[ASIFormDataRequest alloc] initWithURL:url];
//要上传的图片
[ASIFormDataRequest_ setFile:stringImage forKey:@
"file_pic_big"
];
//上传结果委托
ASIFormDataRequest_.delegate=self;
isPoto=YES;
//上传进度委托
ASIFormDataRequest_.uploadProgressDelegate=self;
ASIFormDataRequest_.showAccurateProgress=YES;
//开始异步上传
[ASIFormDataRequest_ startSynchronous];
[ASIFormDataRequest_ release];
}
|
4、处理上传结果
上传结果处理动作同样由requestFinished委托方法负责。上传结果数据,根据API设计的不同,将会返回不一样的标识,读者可根据实际情况进行处理。以下以丽物微博图片上传API为例,代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
//4、异步请求上传结果
- (
void
)requestFinished:(ASIFormDataRequest *)requestForm{
NSString *string=[requestForm responseString];
NSLog(@
"string:%@"
,string);
NSMutableDictionary *_dic=[string JSONValue];
if
([[_dic objectForKey:@
"status"
] intValue]==1) {
if
(isPoto==NO) {
//非图片上传
}
else
{
//图片上传
UtilMethod *utlMethod=[[UtilMethod alloc] init];
NSString *documemnt=[utlMethod documentFolderPath];
NSString *stringImage=[NSString stringWithFormat:@
"%@%@"
,documemnt,@
"/tmp_30.jpg"
];
[utlMethod release];
//可以把30×30的图片显示到界面适当的位置上
}
}
else
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@
"发送失败"
message:[_dic objectForKey:@
"info"
] delegate:self cancelButtonTitle:@
"OK"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
|
ASIFormDataRequest类通过设置uploadProgressDelegate委托,实现对上传数据的实时监控。共有3个委托方法,如下。
1
2
3
4
5
6
|
//累加的已上传百分比
-(
void
)setProgress:(
float
)newProgress;
//不累加的每次上传数据量
-(
void
)request:(ASIHTTPRequest *)request didSendBytes:(
long
long
)bytes;
//累加的数据已上传总量
-(
void
)request:(ASIHTTPRequest *)request incrementUploadSizeBy:(longlong)newLength;
|