iOS开发原生NSURLSession网络请求简单封装
2016-05-20 本文已影响2413人
零壹后学者
(写在前面的话:在iOS开发中,有很多很好用的第三方库,能极大提高开发效率。但是作为一个初学者来说,如果只是单纯地去用第三方,不了解其中的原理,我个人觉得不太好,我也是新人,没事喜欢弄些原生的东西,希望大家多多支持_~好了,废话不多说,开工……)
1.URL:请求路径,个人理解是由App服务器的主路径(NSString *)ServiceUrl + 主题展示的专有接口(NSString *)Api +(NSDictionary *) 参数(get 请求中参数的直接拼在最后的,post请求参数要放到请求体里)三部分组成,本文也是基于这个结构对网络请求进行封装。
2. .h文件(附带一个原生的NSURLConnection上传图片)。
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> // 上传图片用到
@interface KNetWorking : NSObject
@property (strong , nonatomic)AFHTTPSessionManager *manager;
/**
* 原生get请求(NSURLSession)JSON解析
*/
+ (void)getRequestByServiceUrl:(NSString *)service
andApi:(NSString *)api
andParams:(NSDictionary *)params
andCallBack:(void (^)(id obj))callback;
/**
* 原生post请求(NSURLSession)JSON解析
*/
+ (void)postRequestByServiceUrl:(NSString *)service
andApi:(NSString *)api
andParams:(NSDictionary *)params
andCallBack:(void (^)(id obj))callback;
/**
* 原生上传图片
*/
+ (void) postImageWithBaseApi:(NSString *)baseApi
AndPragram:(NSDictionary *)pragram
updatImage:(UIImage *)image
Completion:(void (^) (id obj))completion;
注意这里都是默认返回的是JSON格式的数据
3. .m文件(因为参数是以字典的形式传进来的,所以用了一个 dealWithParam 方法拼接参数)。
// 处理字典参数
+ (NSString *)dealWithParam:(NSDictionary *)param
{
NSArray *allkeys = [param allKeys];
NSMutableString *result = [NSMutableString string];
for (NSString *key in allkeys) {
NSString *str = [NSString stringWithFormat:@"%@=%@&",key,param[key]];
[result appendString:str];
}
return [result substringWithRange:NSMakeRange(0, result.length-1)];
}
// 自带原生的get请求方式
+ (void)getRequestByServiceUrl:(NSString *)service
andApi:(NSString *)api
andParams:(NSDictionary *)params
andCallBack:(void (^)(id obj))callback
{
NSString *basePath = [service stringByAppendingString:api];
NSString *urlString = [NSString string];
// 因为参数是以字典的形式传进来的,所以用了一个 dealWithParam 方法拼接参数。
if (params) {
NSString *paramStr = [self dealWithParam:params];
urlString = [basePath stringByAppendingString:paramStr];
}else
{
urlString = basePath;
}
NSString *pathStr = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:pathStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if (dic) {
callback(dic);
}else
{
callback(error.description);
}
});
}];
[task resume];
}
// 自带原生post请求
+ (void)postRequestByServiceUrl:(NSString *)service
andApi:(NSString *)api
andParams:(NSDictionary *)params
andCallBack:(void (^)(id obj))callback
{
NSString *basePath = [service stringByAppendingString:api];
NSURL *url = [NSURL URLWithString:basePath];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSString *body = [self dealWithParam:params];
NSData *bodyData = [body dataUsingEncoding:NSUTF8StringEncoding];
// 设置请求体
[request setHTTPBody:bodyData];
// 设置本次请求的提交数据格式
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
// 设置本次请求请求体的长度(因为服务器会根据你这个设定的长度去解析你的请求体中的参数内容)
[request setValue:[NSString stringWithFormat:@"%ld",bodyData.length] forHTTPHeaderField:@"Content-Length"];
// 设置本次请求的最长时间
request.timeoutInterval = 20;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if (dic) {
callback(dic);
}else
{
callback(error.description);
}
}];
[task resume];
}
// 原生上传图片
+ (void) postImageWithBaseApi:(NSString *)baseApi AndPragram:(NSDictionary *)pragram updatImage:(UIImage *)image Completion:(void (^) (id obj))completion
{
if (!image) {
return;
}
NSString *sep = @"ABFC134";
// 1:创建ULR
NSURL *url = [NSURL URLWithString:baseApi];
// 2:创建Request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3:设置相关属性
// 3.1设置请求方式
[request setHTTPMethod:@"POST"];
// 3.2处理基本参数(不含图片)
NSArray *allKeys = [pragram allKeys];
NSMutableString *bodyString = [NSMutableString string];
for (NSString *key in allKeys)
{
[bodyString appendFormat:@"--%@\r\n",sep];
NSString *temStr = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",key,pragram[key]];
[bodyString appendString:temStr];
// NSLog(@"%@",bodyString);
}
// 3.3拼上图片
[bodyString appendFormat:@"--%@\r\n",sep];
NSString *imageDes = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n"];
[bodyString appendString:imageDes];
NSString *imageType = [NSString stringWithFormat:@"Content-Type: image/jpeg\r\n\r\n"];
[bodyString appendString:imageType];
// 3.4将图片转换成二进制
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
// 3.5往bodyString中加入图片
// 3.5.1先将bodyString转成二进制
NSMutableData *bodyData = [NSMutableData dataWithData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
[bodyData appendData:imageData];
// 4追加结束标示
NSString *end = [NSString stringWithFormat:@"\r\n--%@--",sep];
[bodyData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
// 5:设置请求体
[request setHTTPBody:bodyData];
//6:设置request的value中content-type
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",sep] forHTTPHeaderField:@"Content-Type"];
// 7:设置请求体的长度
[request setValue:[NSString stringWithFormat:@"%ld",bodyData.length] forHTTPHeaderField:@"Content-Length"];
// 8:设置超时
[request setTimeoutInterval:30.0f];
// 9:发出请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if (dic) {
completion(dic);
}else
{
completion(connectionError.description);
}
}];
}