iOS 纯原生 网络请求 简单封装
问题原因
项目里有用到网络请求,但因为请求相对简单,就没使用现成的什么三方SDK了,就只是将iOS自带的网络请求封装了下。
因为各个项目用到的数据结构和功能可能不一样,所以这里尽可能多的兼容了多种情况,各位可以按需取用。
实现
NetWorkManager.h
#import <Foundation/Foundation.h>
//请求类型枚举
typedef NS_ENUM(NSInteger,NetWorkHTTPMethod) {
NetWorkHTTPMethod_GET,//请求指定页面信息,并返回实体主体
NetWorkHTTPMethod_POST,//向指定的资源提交数据进行处理请求(例如提交表单或上传文件),
//数据被包含在请求体中。post请求可能会导致新的资源的建立或已有资源的修改
NetWorkHTTPMethod_HEAD,//类似隔天请求,只不过返回的响应中没有具体的内容,用于获取报头
NetWorkHTTPMethod_OPTIONS,//允许客户端查看服务器的性能
NetWorkHTTPMethod_PUT,//从客户端向服务器传送的数据取代指定的文档内容。
NetWorkHTTPMethod_DELETE,//请求服务器删除指定的页面
NetWorkHTTPMethod_TRACE,//回显服务器收到的请求,主要用于测试或诊断
NetWorkHTTPMethod_CONNECT,//http/1.1协议中,预留给能够将连接改为管道方式的代理服务器
};
//通讯类型枚举
typedef NS_ENUM(NSInteger,NetWorkContentType) {
NetWorkContentType_JSON,//application/json
NetWorkContentType_PROTOBUF,//application/x-protobuf
NetWorkContentType_PNGIMAGE,//image/png
NetWorkContentType_VIDEOMP4,//video/mpeg4
NetWorkContentType_JPGIMAGE,//image/jpeg
};
NS_ASSUME_NONNULL_BEGIN
@interface NetWorkManager : NSObject
//从网络路径下载文件
+(void)downFile:(NSString *)fileUrl
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//post请求Protobuf格式
+ (void)postForProtobuf:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//post请求Protobuf格式(zip压缩)
+ (void)postForProtobufZip:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//post请求Json格式
+ (void)postForJson:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//post请求Json格式(zip压缩)
+ (void)postForJsonZip:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//put图片请求
+ (void)putForImage:(NSData *)img
withUrl:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//put视频请求
+ (void)putForVideo:(NSData *)vedio
withUrl:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
+ (void)request:(NSString *)url
hTTPMethod:(NetWorkHTTPMethod)method
requestParams:(NSData *)data
heards:(NSDictionary *)header
contentType:(NetWorkContentType)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
+ (void)request:(NSString *)url
hTTPMethod:(NetWorkHTTPMethod)method
requestParams:(NSData *)data
fileData:(NSData*)file
heards:(NSDictionary *)header
contentType:(NetWorkContentType)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
+(void)request:(NSString *)url
hTTPMethodStr:(NSString*)method
requestParams:(NSData *)data
fileData:(NSData*)file
heards:(NSDictionary *)header
contentTypeStr:(NSString*)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//基础网络请求
+(void)request:(NSURLRequest *)request
succeedBlock:(void (^)(NSData * resultdata))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//基础上传文件请求
+(void)request:(NSURLRequest *)request
withData:(NSData *)file
succeedBlock:(void (^)(NSData * resultdata))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock;
//zip压缩文件
+(NSData *)gZipDataWithData:(NSData *)oldData;
@end
NetWorkManager.m
#import "NetWorkManager.h"
#import <zlib.h>
@implementation NetWorkManager
+(void)downFile:(NSString *)fileUrl
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:fileUrl]];
[self request:urlRequest succeedBlock:succeedblock failBlock:failblock];
}
+ (void)postForProtobuf:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_POST requestParams:data heards:header contentType:NetWorkContentType_PROTOBUF needZip:NO succeedBlock:succeedblock failBlock:failblock];
}
+ (void)postForProtobufZip:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_POST requestParams:data heards:header contentType:NetWorkContentType_PROTOBUF needZip:YES succeedBlock:succeedblock failBlock:failblock];
}
+ (void)postForJson:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_POST requestParams:data heards:header contentType:NetWorkContentType_JSON needZip:NO succeedBlock:succeedblock failBlock:failblock];
}
+ (void)postForJsonZip:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_POST requestParams:data heards:header contentType:NetWorkContentType_JSON needZip:YES succeedBlock:succeedblock failBlock:failblock];
}
+ (void)putForImage:(NSData *)img
withUrl:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_PUT requestParams:data fileData:img heards:header contentType:NetWorkContentType_JPGIMAGE needZip:NO succeedBlock:succeedblock failBlock:failblock];
}
+ (void)putForVideo:(NSData *)vedio
withUrl:(NSString *)url
requestParams:(NSData *)data
heards:(NSDictionary *)header
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:NetWorkHTTPMethod_PUT requestParams:data fileData:vedio heards:header contentType:NetWorkContentType_VIDEOMP4 needZip:NO succeedBlock:succeedblock failBlock:failblock];
}
+ (void)request:(NSString *)url
hTTPMethod:(NetWorkHTTPMethod)method
requestParams:(NSData *)data
heards:(NSDictionary *)header
contentType:(NetWorkContentType)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethod:method requestParams:data fileData:nil heards:header contentType:contentType needZip:needZip succeedBlock:succeedblock failBlock:failblock];
}
+(NSString *)stringForNetWorkHTTPMethod:(NetWorkHTTPMethod)type{
NSArray * allNetWorkHTTPMethodString = @[
@"GET",
@"POST",
@"HEAD",
@"OPTIONS",
@"PUT",
@"DELETE",
@"TRACE",
@"CONNECT"
];
return allNetWorkHTTPMethodString[type];
}
+(NSString *)stringForNetWorkContentType:(NetWorkContentType)type{
NSArray * allNetWorkContentTypeString = @[
@"application/json",
@"application/x-protobuf",
@"image/png",
@"video/mpeg4",
@"image/jpeg",
];
return allNetWorkContentTypeString[type];
}
+ (void)request:(NSString *)url
hTTPMethod:(NetWorkHTTPMethod)method
requestParams:(NSData *)data
fileData:(NSData*)file
heards:(NSDictionary *)header
contentType:(NetWorkContentType)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:url hTTPMethodStr:[self stringForNetWorkHTTPMethod:method] requestParams:data fileData:file heards:header contentTypeStr:[self stringForNetWorkContentType:contentType] needZip:needZip succeedBlock:succeedblock failBlock:failblock];
}
+(void)request:(NSString *)url
hTTPMethodStr:(NSString*)method
requestParams:(NSData *)data
fileData:(NSData*)file
heards:(NSDictionary *)header
contentTypeStr:(NSString*)contentType
needZip:(BOOL)needZip
succeedBlock:(void (^)(NSData * data))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setTimeoutInterval:10.0f];// 设置请求超时
[request setHTTPMethod:method]; // 设置请求方法
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];//数据类型为proto格式
if(header && [header.allKeys count]>0){
for (NSString * key in header.allKeys) {
NSString * value = [header objectForKey:key];
[request setValue:value forHTTPHeaderField:key];//自定义请求头参数
}
}
if(needZip){
[request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];//服务端支持gzip压缩
NSData *dataTemp = [self gZipDataWithData:data];//压缩
[request setHTTPBody:dataTemp];
}else{
[request setHTTPBody:data];
}
[self request:request withData:file succeedBlock:succeedblock failBlock:failblock];
}
+(void)request:(NSURLRequest *)request
succeedBlock:(void (^)(NSData * resultdata))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
[self request:request withData:nil succeedBlock:succeedblock failBlock:failblock];
}
+(void)request:(NSURLRequest *)request
withData:(NSData *)file
succeedBlock:(void (^)(NSData * resultdata))succeedblock
failBlock:(void (^)(NSString * errorstr)) failblock{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSURLSessionDataTask *dataTask = nil;
if(file && file.length>0){
dataTask = [session uploadTaskWithRequest:request fromData:file completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if(error){
failblock(error.localizedFailureReason);
}else{
succeedblock(data);
}
});
}];
}else{
dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if(error){
failblock(error.localizedFailureReason);
}else if(data && [data length]>0){
succeedblock(data);
}else{
failblock(@"data is null");
}
});
}];
}
[dataTask resume];
});
}
+(NSData *)gZipDataWithData:(NSData *)oldData
{
float level = -0.1f;
if (oldData.length == 0)
{
return oldData;
}
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = (uint)oldData.length;
stream.next_in = (Bytef *)(void *)oldData.bytes;
stream.total_out = 0;
stream.avail_out = 0;
static const NSUInteger ChunkSize = 16384;
NSMutableData *output = nil;
int compression = (level < 0.0f)? Z_DEFAULT_COMPRESSION: (int)(roundf(level * 9));
if (deflateInit2(&stream, compression, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) == Z_OK)
{
output = [NSMutableData dataWithLength:ChunkSize];
while (stream.avail_out == 0)
{
if (stream.total_out >= output.length)
{
output.length += ChunkSize;
}
stream.next_out = (uint8_t *)output.mutableBytes + stream.total_out;
stream.avail_out = (uInt)(output.length - stream.total_out);
deflate(&stream, Z_FINISH);
}
deflateEnd(&stream);
output.length = stream.total_out;
}
return output;
}
@end
备注
上面很多方法和枚举的定义,是为了外部调用更简洁,可以适当自己增加自己需要的。
这个封装里面,没有进行多请求管理,都是一股脑的异步请求,,所以对于那种网络请求复杂的APP,请谨慎使用。