IOS HTTP 上传图片

本文介绍如何在iOS应用中通过HTTP上传图片,并实现了上传进度的实时监控。包括上传图片的基本代码示例、使用自定义类封装上传操作以及如何在NSURLConnectionDelegate中获取上传进度等关键步骤。

IOS HTTP 上传图片  

2014-04-25 20:15:15|  分类: 学习手记 |  标签:ios  http  上传  图片  |举报|字号 订阅

做一个App需要上传图片。没想使用一些比较出名的开源库,毕竟可以练练手。这里是ASIAFGithub连接,有兴趣的读者可以去看看这些出色的开源库。这里还给出一篇优快云上面的关于这些开源库的表格对比的博客文章
之前在StackOverFlow上面搜过一些关于IOS 上传文件的讨论,下面的代码是参考了上面一个讨论的,读者可以看看这上面的话题讨论
我没有封装一个更好的类来提供完善的接口来完成上传文件的操作,而是直接写Http协议。读者完全可以写一个例如”HttpMultiPartFormatter”之类的类来完成这些工作。下面是代码片段,在我的iphone上跑起来挺好的。
#define MEDIA_CONTENT_TYPE @"multipart/form-data"
#define BOUNDARY_CONSTANT  @"AnyNameYouLike"

@interface UploadViolationTask () <HttpUploadProgressDelegate , HttpDelegate>

@property (nonatomic , strong) HttpOperation *currentOperation;

@end

@implementation UploadViolationTask

- (void)uploadSessionWithPlace:(NSString*)place reason:(NSString*)reason carNumber:(NSString*)carNumber image:(UIImage*)image andImageFileName:(NSString*)fileName
{
    HttpOperation *operation = [[HttpOperation alloc] init];
    self.currentOperation = operation;
    
    [operation setUrl:URL_SendViolationSession];
    [operation setTimeOut:30];
    [operation setOperationDescription:@"SaveViolationSession"];
    [operation setContentType:MEDIA_CONTENT_TYPE withBoundary:BOUNDARY_CONSTANT];
    [operation setMethod:@"POST"];
    [operation setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [operation setHTTPShuoldHandleCookes:NO];
    
    [operation setUploadProgressDelegate:self];
    [operation setCommonDelegate:self];

    NSString *userID = [[PersonalInfoRecorder sharedInstance] userID];
    NSString *schoolID = [[PersonalInfoRecorder sharedInstance] schoolID];
    
    NSMutableData *body = [[NSMutableData alloc] init];
    NSDictionary *params = [[NSDictionary alloc] initWithObjectsAndKeys:place , @"illegal.place" , reason , @"illegal.type.id" ,  carNumber , @"illegal.vehPlate" , userID , @"illegal.creation.id" , schoolID , @"illegal.schoolInfo", fileName , @"fileFileName" ,  nil];
    
    /* Add the attach params at first */
    for(NSString* param in [params allKeys])
    {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n" , BOUNDARY_CONSTANT] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n" , param] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", [params valueForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
    }
 
    /* Add the image content */
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n" , BOUNDARY_CONSTANT] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n" , fileName] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n" dataUsingEncoding:NSUTF8StringEncoding] ];
    [body appendData:[@"Content-Transfer-Encoding: binary\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData: UIImageJPEGRepresentation(image, 0.1)];
    [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n" , BOUNDARY_CONSTANT] dataUsingEncoding:NSUTF8StringEncoding]];
    
    [operation setPostLength:[body length]];
    [operation setBody:body];
    [operation submit];
}
  里面的一些常量大家自己定义就好了。里面的图片的Content-Type: application/octet-streams 是要告诉服务器这是个任意的二进制文件。因为以后封装起来,还可以用来读其他的文件类型,所以就随便用了这个。当然你要准确的话,你可以写成image/jpeg 或者 image/png这样来表示这是一个文件文件。

----------------------------------------------------------

顺带一提的是关于IOS里面 NSURLConnection的上传进度的问题。这个其实很简单,在NSURLConnectionDelegate里面有一个方法可以知道本次上传数据量,当前上传数据总量和总共要上传数据量的。也顺便贴一下代码吧。
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    /* bytesWritten                     How many bytes were sent to server at this time */
    /* totalBytesWritten               The number of bytes that were sent to the server currently */
    /* totalBytesExpectedToWrite     The number of bytes that we want to send to the server */
    CGFloat progress   = totalBytesWritten / (CGFloat)totalBytesExpectedToWrite;
    if([self.uploadProgressDelegate respondsToSelector:@selector(httpOperation:updatedToNewProgress:)])
    {
        [self.uploadProgressDelegate httpOperation:self updatedToNewProgress:progress];
    }
}
在那个delegate里面你就可以用progress来刷新你的进度条啦。
就这么多吧。不知道打错了多少字。下班咧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值