// 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