// SHNetworkTool.h
#import
<Foundation/Foundation.h>
// 定义 block 类型:
// 1. 成功回调 参数类型:二进制数据和响应头信息.
typedef void(^SuccessBlock)(id responseObj , NSURLResponse *response);
// 2. 失败回调
typedef void(^failBlock)(NSError *error);
@interface SHNetworkTool : NSObject
// 网络工具类 单例
// 带参数的网络请求:POST
// urlString: 网络接口.
// paramaters: 参数字典. key(服务器接收参数的key值) = value(key对应的参数内容)
// success : 网络成功的回调
// fail : 网络失败的回调
-(void)POSTdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail;
// 带参数的网络请求:GET
// urlString: 网络接口.
// paramaters: 参数字典. key(服务器接收参数的key值) = value(key对应的参数内容)
// success : 网络成功的回调
// fail : 网络失败的回调
- (void)GETdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail;
// 多文件上传.网络完成之后的回调.
// completionHandler:如果后台返回的是JSON 数据,自动解析之后,将JSON 数据传递给外界 (responseObj:就是JSON解析之后的数据.)如果不是JSON 数据,直接传给外界 data(responseObj:就是 NSData) .
- (void)POSTuploadWithUrlString:(NSString *)urlString fileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters completionHandler:(void (^)(id responseObj, NSURLResponse * response, NSError *error))completionHandler;
// 自动封装多文件+多普通参数上传的请求体格式.
// fileDict : 文件参数字典
// fileKey : 服务器接收文件参数的 key 值.
// paramaters : 普通参数字典
- (NSData *)getHttpBodyWithfileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters;
//实例化单例的方法.
+(instancetype)sharedNetworkTool;
// 网络请求完成之后,应该有成功和失败.
// 定义两个Block :成功回调/失败回调.
// 发送网络请求的方法
// urlString :网络接口
// 两个 block 参数
// 1.successBlk 成功回调
// 2.failBlk 失败回调
-(void)getServerDataWithUrlString:(NSString *)urlString Success:(SuccessBlock)successBlk Fail:(failBlock)failBlk;
// 定义 block 类型:
// 1. 成功回调 参数类型:二进制数据和响应头信息.
typedef void(^SuccessBlock)(id responseObj , NSURLResponse *response);
// 2. 失败回调
typedef void(^failBlock)(NSError *error);
@interface SHNetworkTool : NSObject
// 网络工具类 单例
// 带参数的网络请求:POST
// urlString: 网络接口.
// paramaters: 参数字典. key(服务器接收参数的key值) = value(key对应的参数内容)
// success : 网络成功的回调
// fail : 网络失败的回调
-(void)POSTdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail;
// 带参数的网络请求:GET
// urlString: 网络接口.
// paramaters: 参数字典. key(服务器接收参数的key值) = value(key对应的参数内容)
// success : 网络成功的回调
// fail : 网络失败的回调
- (void)GETdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail;
// 多文件上传.网络完成之后的回调.
// completionHandler:如果后台返回的是JSON 数据,自动解析之后,将JSON 数据传递给外界 (responseObj:就是JSON解析之后的数据.)如果不是JSON 数据,直接传给外界 data(responseObj:就是 NSData) .
- (void)POSTuploadWithUrlString:(NSString *)urlString fileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters completionHandler:(void (^)(id responseObj, NSURLResponse * response, NSError *error))completionHandler;
// 自动封装多文件+多普通参数上传的请求体格式.
// fileDict : 文件参数字典
// fileKey : 服务器接收文件参数的 key 值.
// paramaters : 普通参数字典
- (NSData *)getHttpBodyWithfileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters;
//实例化单例的方法.
+(instancetype)sharedNetworkTool;
// 网络请求完成之后,应该有成功和失败.
// 定义两个Block :成功回调/失败回调.
// 发送网络请求的方法
// urlString :网络接口
// 两个 block 参数
// 1.successBlk 成功回调
// 2.failBlk 失败回调
-(void)getServerDataWithUrlString:(NSString *)urlString Success:(SuccessBlock)successBlk Fail:(failBlock)failBlk;
@end
//
// SHNetworkTool.m
// SHNetworkTool.m
#import "SHNetworkTool.h"
#define kBoundary @"kboundary"
@implementation SHNetworkTool
-(void)POSTdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail
{
// 作业:
}
- (void)GETdataWithUrlString:(NSString *)urlString paramaters:(NSDictionary *)paramaters SuccessBlock:(SuccessBlock)success FailBlock:(failBlock)fail
{
// GET 请求的参数都拼接在url中,以 ? 分隔. 参数和参数之间以 & 分隔
NSMutableString *str = [NSMutableString stringWithFormat:@"%@?",urlString];
// 遍历参数字典,将参数拼接在 url 后面
[paramaters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 服务器接收参数的 key 值.
NSString *paramaterKey = key;
// 参数内容
NSString *paramater = obj;
[str appendFormat:@"%@=%@&",paramaterKey,paramater];
}];
NSString *urlStr = [str substringToIndex:str.length - 1];
NSLog(@"%@",urlStr);
// 1. 创建网络请求
NSURL *url = [NSURL URLWithString:urlStr];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2 .发送请求
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data && !error) { // 网络成功
// JSON 解析 JSON --> OC
id Obj = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
if (!Obj) {
Obj = data;
}
// 执行 成功回调.
if (success) {
success(Obj,response);
}
}else
{
// 执行网络失败回调.
if (fail) {
fail(error);
}
}
}] resume];
}
- (void)POSTuploadWithUrlString:(NSString *)urlString fileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters completionHandler:(void (^)(id, NSURLResponse *, NSError *))completionHandler
{
// 百分号转译
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求方法
request.HTTPMethod = @"POST";
NSString *type = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",kBoundary];
// 设置 Content-Type
[request setValue:type forHTTPHeaderField:@"Content-Type"];
// 设置请求体
request.HTTPBody = [self getHttpBodyWithfileDict:fileDict fileKey:fileKey paramaters:paramaters];
// 发送请求
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 网络完成. 回调自己写的 block(completionHandler)
// 解析 JSON 数据.
id obj = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
if (!obj) { // 如果 data 不是 JSON 数据, obj = data.
obj = data;
}
// 执行 block 回调.
if (completionHandler) {
completionHandler(obj,response,error);
}
}] resume];
}
// fileDict : 文件参数字典
// fileKey : 服务器接收文件参数的 key 值.
// paramaters : 普通参数字典
- (NSData *)getHttpBodyWithfileDict:(NSDictionary *)fileDict fileKey:(NSString *)fileKey paramaters:(NSDictionary *)paramaters
{
// 实例化空的请求体内容.
NSMutableData *data = [NSMutableData data];
// 1. 遍历文件参数字典,拼接文件参数格式.
[fileDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 文件路径
NSString *filePath = key;
// 文件名称
NSString *fileName = obj;
// 拼接文件格式:
// 1. 文件的上边界 headerStrM
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",kBoundary];
[headerStrM appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",fileKey,fileName];
[headerStrM appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"];
// 将文件上边界添加到请求体中
[data appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
// 2. 文件内容
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
// 将文件内容添加到请求体中
[data appendData:fileData];
}];
// 2. 遍历普通参数字典,拼接普通参数的上传格式.
[paramaters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 服务器接收参数的 key 值.
NSString *paramaterKey = key;
// 参数内容
NSString *paramater = obj;
// 拼接普通参数的上传格式.
// 1. 普通参数上边界
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",kBoundary];
[headerStrM appendFormat:@"Content-Disposition: form-data; name=%@\r\n\r\n",paramaterKey];
// 将普通参数上边界添加到请求体中
[data appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
// 2. 普通参数内容
NSData *paramaterData = [paramater dataUsingEncoding:NSUTF8StringEncoding];
// 将普通参数内容添加到请求体中
[data appendData:paramaterData];
}];
// 下边界内容
NSMutableString *footerStrM = [NSMutableString stringWithFormat:@"\r\n--%@--",kBoundary];
// 将下边界内容添加到请求体中
[data appendData:[footerStrM dataUsingEncoding:NSUTF8StringEncoding]];
return data;
}
-(void)getServerDataWithUrlString:(NSString *)urlString Success:(SuccessBlock)successBlk Fail:(failBlock)failBlk
{
// 1. 创建请求
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
// 2. 发送网络请求
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 网络请求完成之后的回调.
// 成功:
if (data && !error) {
// 执行成功回调.
dispatch_async(dispatch_get_main_queue(), ^{
// 3.执行成功回调.
if (successBlk) {
successBlk(data,response);
}
});
}else // 失败
{
if (failBlk) {
// 3.执行失败回调.
failBlk(error);
}
}
}] resume];
}
+(instancetype)sharedNetworkTool
{
static id _instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
@end