NSURLConnection(苹果原生上传单文件)
来源:互联网 发布:看小说软件排行 编辑:程序博客网 时间:2024/05/21 16:00
其实NSURLConnection在iOS7.0之后就逐渐被NSURLSession取代,尤其是iOS9.0出来之后,基本很少有公司再去适配iOS7.0之前的用户了,当然可能,某些比较老旧的项目依然保留着NSURLConnection+NSOperation实现网络请求。就像AFN依旧保留着AFHTTPRequestOperationManager接口。通过
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || TARGET_WATCH_OS
宏定义,实现跨版本的适配。
那么NSURLConnection和NSURLSession的区别到底在哪呢?
- 异步请求不需要NSOperation包装
- 支持后台运行的网络任务(后台上传下载)
- 根据每个Session做配置,不需要在整个app层面共享配置
- 支持网络操作的取消和断点续传(继承系统类,重写main方法)
- 改进的了授权机制的处理
以下就是通过NSURLConnection实现的文件上传代码,老早之前写的了,因为开发中使用到的地方还是非常少的,除非是遇到AFN上传解决不了的时候,这时候才会去想到回归原生方法去实现上传,比如说上传某些音频文件的时候,有时候AFN就不能完成上传。
注意:
- POST实现⽂文件上传,采⽤用NSURLConnection发送异步请求。
- 调⽤用API需要知参数:
服务器地址(上传文件脚本地址)
服务器允许上传⽂文件key值 ⽂文件名(key)+本地⽂文件路径(value)
服务器允许上传⽂文本⽂文件的key值(key)+⽂文本内容(value)
#import <Foundation/Foundation.h>@interface XYUploadManager : NSObject+ (instancetype)sharedXYUploadManager;//上传文件的API- (void)postFileToServer:(NSString *)serverUrl serverKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict paramater:(NSDictionary *)paramater;//格式化上传数据- (NSData *)getHttpBodyDataWithServerKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict;//格式化上传数据,附带文本信息- (NSData *)getHttpBodyDataWithServerKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict paramater:(NSDictionary *)paramater;@end
//宏定义请求公共字符串#define kBoundary @"Boundary"#import "XYUploadManager.h"@implementation XYUploadManager/** * 单例上传文件工具类 * * @return 实例化单例对象 */+ (instancetype)sharedXYUploadManager{ static id _instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance;}/** * 上传文件API接口 * * @param serverUrl 请求服务器地址 * @param fileDict 文件名称:fileName(key)= 文件路径filePath(value) * @param paramater 服务器接收上传文件key = 上传的文本信息value */- (void)postFileToServer:(NSString *)serverUrl serverKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict paramater:(NSDictionary *)paramater{ NSURL *url = [NSURL URLWithString:serverUrl]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",kBoundary]; [request setValue:contentType forHTTPHeaderField:@"Content-Type"]; request.HTTPBody = [self getHttpBodyDataWithServerKey:serverKey fileDict:fileDict paramater:paramater]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { }];}/** * 格式化上传数据(只有文件信息) * * @param serverKey 服务器接受上传文件的key值 * @param fileDict 文件名称:fileName(key)= 文件路径filePath(value) * * @return 上传的二进制数据 */- (NSData *)getHttpBodyDataWithServerKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict{ NSMutableData *data = [NSMutableData data];// 遍历上传参数的数据字典,将上传文件路径和保存的名称都取出来 [fileDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSString *fileName = key; NSString *filePath = obj; NSMutableString *headerStr = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",kBoundary]; [headerStr appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",serverKey,fileName];// 获取上传文件的类型 NSString *contentType = [self getFileMIMETypeWithFilePath:filePath]; [headerStr appendFormat:@"Content-Type: %@\r\n\r\n",contentType];// 获取上边界的二进制数据 NSData *headerData = [headerStr dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:headerData];// 获取上传文件的二进制数据 NSData *fileData = [NSData dataWithContentsOfFile:filePath]; [data appendData:fileData]; }];// 整个上传数据文件的下边界(或每个上传文件都可以有个自己的下边界) NSMutableString *footerStr = [NSMutableString stringWithFormat:@"\r\n--%@--\r\n",kBoundary];// 获取下边界的二进制数据 NSData *footerData = [footerStr dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:footerData]; return data;}/** * 格式化上传数据(含文本信息) * * @param serverKey 服务器接受上传文件的key值 * @param fileDict 文件名称:fileName(key)= 文件路径filePath(value) * @param paramater 服务器接受文本文件key = 上传的文本信息value * * @return 上传文件的二进制数据 */- (NSData *)getHttpBodyDataWithServerKey:(NSString *)serverKey fileDict:(NSDictionary *)fileDict paramater:(NSDictionary *)paramater{ NSMutableData *data = [NSMutableData data];// 遍历上传参数的数据字典,将上传文件路径和保存的名称都取出来 [fileDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSString *fileName = key; NSString *filePath = obj; NSMutableString *headerStr = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",kBoundary]; [headerStr appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",serverKey,fileName];// 获取上传文件的类型 NSString *contentType = [self getFileMIMETypeWithFilePath:filePath]; [headerStr appendFormat:@"Content-Type: %@\r\n\r\n",contentType];// 获取上边界的二进制数据 NSData *headerData = [headerStr dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:headerData];// 获取上传文件的二进制数据 NSData *fileData = [NSData dataWithContentsOfFile:filePath]; [data appendData:fileData]; }];// 文本信息 [paramater enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {// key:服务器接收文本信息的key值// obj:上传到服务器的文本信息 NSMutableString *headerStr = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",kBoundary]; [headerStr appendFormat:@"Content-Disposition: form-data; name=%@\r\n\r\n",key]; NSData *headerData = [headerStr dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:headerData]; NSString *str = obj; NSData *strData = [str dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:strData]; }];// 整个上传数据文件的下边界(或每个上传文件都可以有个自己的下边界) NSMutableString *footerStr = [NSMutableString stringWithFormat:@"\r\n--%@--\r\n",kBoundary];// 获取下边界的二进制数据 NSData *footerData = [footerStr dataUsingEncoding:NSUTF8StringEncoding]; [data appendData:footerData]; return data;}/** * 获取上传文件类型 * * @param path 本地文件的路径 * * @return Content-Type */- (NSString *)getFileMIMETypeWithFilePath:(NSString *)path{// 本地文件的url NSString *urlStr = [NSString stringWithFormat:@"file://%@",path];// 中文路径百分号转译 urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url = [NSURL URLWithString:urlStr]; NSURLRequest *request = [NSURLRequest requestWithURL:url];// 定义响应对象,服务器的响应要放在这个响应对象中 NSURLResponse *response = nil; [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL]; // 文件类型:response中的属性 return response.MIMEType;}@end
通过这坨代码以及我刚才发的简单封装AFN的工具类的代码就能看出,为什么在实际开发中不使用苹果原生的网络访问方法了吧,太繁琐了。但是,第三方框架再牛逼也是基于对苹果原生的封装,如果想要提升自己,还是要从原生一步一步搞懂实现原理,将来才有可能成为像AFN作者这样的大牛,当然,如果只是为了完成开发的网络请求,直接AFN的GET/POST就能满足你的要求了!
0 0
- NSURLConnection(苹果原生上传单文件)
- NSURLConnection文件上传
- NSURLConnection文件上传&&解压缩
- IOS NSURLConnection 文件上传
- IOS使用NSURLConnection实现文件上传
- springmvc文件上传(原生)
- PHP原生--文件上传
- H5原生文件上传
- 文件上传 - JAVA原生
- 原生上传文件
- php原生文件上传
- 原生方式上传文件
- 仿web中的form表单使用苹果原生网络请求进行文件上传
- 文件上传(二)原生一般文件上传
- NSURLConnection苹果官方文档
- 原生js异步文件上传
- php 原生的文件上传
- 使用原生HTML5上传文件
- 总结几种应用于WPF的Chart插件
- String类的不可变性
- VS2010调试之“编辑并继续”
- CButtonST类简介
- 缺陷报告
- NSURLConnection(苹果原生上传单文件)
- Android下Xml解析技术(二)、DOM解析Xml文件
- sola
- 利用反射复制数据
- JDBC原理
- ACRush 楼天成回忆录
- iOS 静态库开发
- VS2010 调试技巧
- Android下Xml解析技术(三)、pull解析Xml文件