以AFNetworking 3.1.0为例,可以用 CocoaPods 把库导入到工程中。
- 接口请求基础类:
#import <Foundation/Foundation.h>
#import "AFHTTPSessionManager.h"
@interface ZLAppBaseService : NSObject
@property (nonatomic,strong)AFHTTPSessionManager *manager;
@property (nonatomic,copy) NSString *urlStr;//请求链接 //默认使用[SCSysconfig webAPI]作为根路径
@property(nonatomic,copy) NSString *action; //操作名
@property(nonatomic,copy) NSString *service; //服务名
@property(nonatomic,copy) NSString *method; //方法名
@property(nonatomic,copy) NSString *downloadPath; //下载文件保存地址,默认使用[SCSysconfig filePathByName:[self url]]
@property(nonatomic,strong) NSMutableDictionary *headers; //头信息
@property(nonatomic,strong) NSMutableDictionary *params; //传递参数
-(NSURLSessionDataTask *)requestMethodType:(NSString *)methodType result:(void (^)(NSString *, NSString *))finish;
-(NSURLSessionDataTask *)getRequest:(void (^)(NSString *, NSString *))finish;
-(NSURLSessionDataTask *)postRequest:(void (^)(NSString *, NSString *))finish;
-(NSURLSessionDataTask *)upload:(void (^)(NSString *,NSString *))finish;
-(NSURLSessionDataTask *)uploadWithProgressBlock:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(NSString *,NSString *))finish;
-(NSURLSessionDataTask *)download:(void (^)(NSString *,NSString *))finish;
-(NSURLSessionDataTask *)downloadWithProgressBlock:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(NSString *,NSString *))finish;
@end
#import "ZLAppBaseService.h"
@interface AFHTTPSessionManager (Singleton)
+(instancetype)shareManager;
@end
@implementation AFHTTPSessionManager (Singleton)
+(instancetype)shareManager
{
static AFHTTPSessionManager *manager = nil;
static dispatch_once_t token ;
dispatch_once(&token, ^{
manager = [[AFHTTPSessionManager alloc] init];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
});
return manager;
}
@end
@implementation ZLAppBaseService
-(id)init
{
self = [super init];
if (self) {
_manager = [AFHTTPSessionManager shareManager];
self.urlStr=defaultURL;//设置默认的请求链接
// class_replaceMethod(toolClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
}
return self;
}
-(NSURLSessionDataTask *)requestMethodType:(NSString *)methodType result:(void (^)(NSString *, NSString *))finish
{
if ([methodType isEqualToString:@"GET"]) {
return [self getRequest:finish];
}else if ([methodType isEqualToString:@"POST"]){
return [self postRequest:finish];
}
return nil;
}
#pragma mark ----------- get请求 -------------------------
-(NSURLSessionDataTask *)getRequest:(void (^)(NSString *, NSString *))finish
{
return [self.manager GET:[self generateURL] parameters:self.params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (finish) {//如果实现finish block块
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
finish(responseString,nil);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败\n%@\n%@",[self description],[error description]);
if(finish){
finish(nil,@"请求失败");
}
}];
}
#pragma mark ----------- post请求 -------------------------
-(NSURLSessionDataTask *)postRequest:(void (^)(NSString *, NSString *))finish
{
return [self.manager POST:[self generateURL] parameters:self.params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (finish) {//如果实现finish block块
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
finish(responseString,nil);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败\n%@\n%@",[self description],[error description]);
if(finish){
finish(nil,@"请求失败");
}
}];
}
#pragma mark ----------- 上传 -------------------------
-(NSURLSessionDataTask *)upload:(void (^)(NSString *,NSString *))finish
{
return [self uploadWithProgressBlock:nil finish:finish];
}
-(NSURLSessionDataTask *)uploadWithProgressBlock:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(NSString *,NSString *))finish
{
return [self.manager POST:[self generateURL] parameters:self.params
progress:^(NSProgress * _Nonnull uploadProgress) {
if (progressBlock) {
NSInteger pro = uploadProgress.fractionCompleted*100 ;
NSLog(@"上传进度百分比 ---- %f%%",pro);
NSLog(@"上传进度 ---- %lld",uploadProgress.completedUnitCount);
if (progressBlock) {
progressBlock(uploadProgress,pro);
}
}
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (finish) {//如果实现finish block块
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
finish(responseString,nil);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败\n%@\n%@",[self description],[error description]);
if(finish){
finish(nil,@"请求失败");
}
}];
}
#pragma mark -------------- 下载 ----------------------
-(NSURLSessionDataTask *)download:(void (^)(NSString *, NSString *))finish
{
return [self downloadWithProgressBlock:nil finish:finish];
}
-(NSURLSessionDataTask *)downloadWithProgressBlock:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(NSString *, NSString *))finish
{
return [self.manager GET:[self generateURL] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
NSInteger pro = downloadProgress.fractionCompleted*100 ;
NSLog(@"下载进度百分比 ---- %ld%%",(long)pro);
NSLog(@"下载进度 ---- %lld",downloadProgress.completedUnitCount);
if (progressBlock) {
progressBlock(downloadProgress,pro);
}
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (finish) {
NSLog(@"下载完成 --- %@ ",responseObject);
finish(responseObject,nil);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败\n%@\n%@",[self description],[error description]);
if(finish){
finish(nil,@"请求失败");
}
}];
}
-(void)setUrlStr:(NSString *)urlStr{
if([urlStr isNotEmpty] && ![urlStr hasPrefix:@"http://"] && ![urlStr hasPrefix:@"https://"]){
urlStr=[@"http://" stringByAppendingString:urlStr];
}
_urlStr=urlStr;
}
-(NSString *)generateURL{
NSMutableString *url=[NSMutableString string];
if(_urlStr){
[url appendString:_urlStr];
}
if(_action){
[url appendFormat:@"/%@",_action];
}
//c#
if(_service){
[url appendFormat:@"/%@",_service];
if(_method){
[url appendFormat:@"/%@",_method];
}
}
//java
else{
if(_method){
[url appendFormat:@"/%@",_method];
}
}
return url;
}
-(NSString *)description{
NSString *urlStr=[self generateURL];
NSURL *url=[NSURL URLWithString:urlStr relativeToURL:[NSURL URLWithString:defaultURL]];
urlStr=url.absoluteString;
NSMutableArray *arr=[NSMutableArray new];
for(NSString *key in [_params allKeys]){
NSString *str=[key stringByAppendingFormat:@"=%@",[_params[key] isNotEmpty]?_params[key]:@""];
[arr addObject:str];
}
NSString *params=[arr componentsJoinedByString:@"&"];
if(params){
urlStr=[urlStr stringByAppendingFormat:@"?%@",params];
}
return urlStr;
}
@end
- model类
关于用 JSONModel 的好处 可以参考:https://www.jianshu.com/p/3cce56f374b4
#import <Foundation/Foundation.h>
#import "JSONModel.h"
@interface ZLJSONModel : JSONModel
@end
@interface ZLDataResult : NSObject
@property (nonatomic,assign)int ResultCode;//请求状态
@property (nonatomic,strong )id Value;
@property (nonatomic,copy)NSString *ResultMessage;
@property (nonatomic,copy)NSString *SynDate;
@end
@interface ZLUserInfo : ZLJSONModel
@property (nonatomic,assign) int IsVisitor;
@property (nonatomic,assign) int allscore;
@property (nonatomic,assign) int nextscore;
@property (nonatomic,assign) int syscore;
@property (nonatomic,assign) long userid;
@property (nonatomic,assign) long xxtclasscode;
@property (nonatomic,assign) int usertype;
@property (nonatomic,assign) int vip;
@property (nonatomic,copy)NSString *babyname;
@property (nonatomic,copy)NSString *babypic;
@property (nonatomic,copy)NSString *truename;
@property (nonatomic,assign) int casteid;
@property (nonatomic,assign) int classid;
@property (nonatomic,assign) int daynum;
@property (nonatomic,assign) int grade;
@property (nonatomic,assign) int haveprize;
@property (nonatomic,copy)NSString *payendtime;
@property (nonatomic,assign)long schoolcode;
@property (nonatomic,copy)NSString *schoolname;
@property (nonatomic,copy)NSString *stuclass;
@property (nonatomic,assign)long sex;
@property (nonatomic,copy)NSString *teapower;
@end
/*
广告
*/
@interface ZLAdvertisement : ZLJSONModel
@property (nonatomic,assign)int id;
@property (nonatomic,assign)int type;
@property (nonatomic,copy) NSString *img_url;
@property (nonatomic,copy) NSString *title;
@property (nonatomic,copy) NSString *html_jump_url;//点击广告后跳转的详情页链接 使用key映射后的字段
@property (nonatomic,assign) int html_jump_type;//点击广告后跳转的类型 使用key映射后的字段
@property (nonatomic,copy) NSString *start_time;
@property (nonatomic,copy) NSString *end_time;
@end
#import "ZLDataDefine.h"
@implementation ZLJSONModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation ZLDataResult
@end
@implementation ZLUserInfo
@end
@implementation ZLAdvertisement
/**
JSONModel 中 的 key映射
@return JSONKeyMapper
*/
+(JSONKeyMapper *)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"list.extra.url":@"html_jump_url",@"list.extra.jump_type":@"html_jump_type"}];
}
@end
上面ZLAdvertisement 的keyMapper中的映射 可供参考的请求数据结果:
{
"status": 1,
"error": "",
"data": {
"timestamp": 1538476302,
"list": [{
"start_time": 1538409600,
"end_time": 1538668800,
"title": "音乐故事Vol.134 有时差的爱情,你早,我晚",
"id": 645,
"type": 4,
"img_url": "http://imge.kugou.com/v2/mobile_class_banner/1bafcec5956263a3f084abd65d0d8aae.jpg",
"extra": {
"url": "http://tpl.mobile.kugou.com/topic/5bb09adadea80b1dde66172b.html",
"jump_type": 0
}
} ]
},
"errcode": 0
}
- 接口解析类
#import <Foundation/Foundation.h>
/**
* 接口数据解析类
*/
@interface ZLProtocolParser : NSObject
/**
解析请求结果
@param reponseDic 网络请求的 数据结果
@param className 你想要解析成的对象
@return ZLDataResult
*/
+(ZLDataResult *)parserObject:(NSDictionary *)reponseDic WithClass:(Class)className;
/**
解析请求结果
@param responseDic 网络请求的 数据结果
@param name 通过name字段进行获取数据
@param className 你想要解析成的对象
@return ZLDataResult
*/
+ (ZLDataResult *)parseObject:(NSDictionary *)responseDic objectName:(NSString *)name withClass:(Class)className;
/**
解析请求结果
@param responseDic 网络请求的 数据结果
@param className 你想要解析成的对象
@return ZLDataResult
*/
+ (ZLDataResult *)parseArray:(NSDictionary *)responseDic withClass:(Class)className;
/**
解析请求结果
@param responseDic 网络请求的 数据结果
@param name 通过name字段进行获取数据
@param className 你想要解析成的对象
@return ZLDataResult
*/
+ (ZLDataResult *)parseArray:(NSDictionary *)responseDic listName:(NSString *)name withClass:(Class)className;
+ (NSDictionary *)parseDictionary:(NSString *)response;
@end
#import "ZLProtocolParser.h"
@implementation ZLProtocolParser
+(ZLDataResult *)parserObject:(NSDictionary *)responseDic WithClass:(Class)className
{
ZLDataResult *result = [[ZLDataResult alloc] init];
result.ResultCode = [responseDic[@"ResultCode"] intValue];
result.ResultMessage = responseDic[@"ResultMessage"];
result.SynDate = responseDic[@"SynDate"];
NSError *error = nil;
JSONModel *data = [[className alloc] initWithDictionary:responseDic error:&error];
if (error) {
NSLog(@"ERROR [parseObject:withClass:] \n%@",error);
return result;
}
result.Value = data;
return result;
}
+ (ZLDataResult *)parseObject:(NSDictionary *)responseDic objectName:(NSString *)name withClass:(Class)className {
ZLDataResult *result = [[ZLDataResult alloc] init];
result.ResultCode = [responseDic[@"ResultCode"] intValue];
result.ResultMessage = responseDic[@"ResultMessage"];
result.SynDate = responseDic[@"SynDate"];
NSDictionary *dataDic = responseDic[name];
NSError *error = nil;
JSONModel *data = [[className alloc] initWithDictionary:dataDic error:&error];
if (error) {
NSLog(@"ERROR [parseObject:withClass:] \n%@",error);
return result;
}
result.Value = data;
return result;
}
+ (ZLDataResult *)parseArray:(NSDictionary *)responseDic withClass:(Class)className {
return [self parseArray:responseDic listName:@"list" withClass:className];
}
+ (ZLDataResult *)parseArray:(NSDictionary *)responseDic listName:(NSString *)name withClass:(Class)className {
ZLDataResult *result = [[ZLDataResult alloc] init];
result.ResultCode = [responseDic[@"ResultCode"] intValue];
result.ResultMessage = responseDic[@"ResultMessage"];
result.SynDate = responseDic[@"SynDate"];
NSArray *arr = responseDic[name];
NSError *error = nil;
NSMutableArray *resultArr = [NSMutableArray new];
for (NSDictionary *dic in arr) {
JSONModel *modelData = [[className alloc] initWithDictionary:dic error:&error];
[resultArr addObject:modelData];
if (error) {
NSLog(@"ERROR [parseArray:withClass:] \n%@",error);
return result;
}
}
result.Value= resultArr;
return result;
}
+ (NSDictionary *)parseDictionary:(NSString *)response {
NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
id obj = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
if (error) {
NSLog(@"ERROR [parseDictionary:] \n%@",error);
return nil;
}
return obj;
}
@end
- 接口请求类 (所有接口请求 放在同一个类中,方便管理)
#import <Foundation/Foundation.h>
/**
网络请求数据回调block
@param result 服务器响应数据源
*/
typedef void(^DataHandle)(ZLDataResult *result);
@interface ZLProtocolInterface : NSObject
/**
登录
@param userpwd 账号
@param userpwd 密码
@param dataHandle 返回值
*/
+(void)reqLoginNew:(NSString *)username userpwd:(NSString *)userpwd completion:(DataHandle)dataHandle;
/**
广告
@param dataHandle 返回值
*/
+(void)reqAdvertisementWithAction:(DataHandle)dataHandle;
#pragma mark ------------ 听吧 --------------
/**
推荐歌单
@param type 歌单类型
@param page 页数
@param pages 一页数据的个数
@param dataHandle 返回值
*/
+(void)reqMusicSheetListWithType:(NSInteger)type page:(int)page pages:(int)pages completion:(DataHandle)dataHandle;
/**
热门歌曲
@param dataHandle 返回值
*/
+(void)reqMusicHotList:(DataHandle)dataHandle;
/**
收藏列表
@param userid 用户id
@param typeid 收藏歌曲类型id
@param page 页数
@param pages 一页数据的个数
@param dataHandle 返回值
*/
+(void)reqCollectionList:(NSString *)userid typeid:(long)typeid
page:(int)page pages:(int)pages completion:(DataHandle)dataHandle;
/**
播放歌曲的历史记录
@param userid 用户id
@param page 页数
@param pages 一页数据的个数
@param dataHandle 返回值
*/
+(void)reqMusicHistoryListNew:(NSString *)userid page:(int)page pages:(int)pages completion:(DataHandle)dataHandle;
@end
#import "ZLProtocolInterface.h"
@implementation ZLProtocolInterface
/**
网络请求
@param action 请求的 操作名(服务器名)
@param method 请求的 方法名
@param params 请求 字段
@param finish 请求 结果
*/
+ (void)reqWithAction:(NSString *)action method:(NSString *)method params:(NSDictionary *)params methodType:(NSString *)methodType finish:(void (^)(id))finish {
ZLAppBaseService *service = [[ZLAppBaseService alloc] init];
service.action = action;
service.method = method;
service.params = [params mutableCopy];
[service requestMethodType:@"GET" result:^(NSString *response, NSString *error) {
if (error) {
NSLog(@"Error [reqWithAction:method:params:finish:]\n%@",error);
finish(nil);
}else {
NSDictionary *resultDic = [ZLProtocolParser parseDictionary:response];
finish(resultDic);
}
}];
}
+ (void)reqWithURL:(NSString *)url params:(NSDictionary *)params
methodType:(NSString *)methodType finish:(void (^)(id))finish {
ZLAppBaseService *service = [[ZLAppBaseService alloc] init];
service.urlStr = url;
service.params = [params mutableCopy];
[service requestMethodType:methodType result:^(NSString *response, NSString *error) {
if (error) {
NSLog(@"Error [reqWithAction:method:params:finish:]\n%@",error);
finish(nil);
}else {
NSDictionary *resultDic = [ZLProtocolParser parseDictionary:response];
finish(resultDic);
}
}];
}
+ (void)reqWithURL:(NSString *)url params:(NSDictionary *)params uploadWithProgress:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(id))finish {
ZLAppBaseService *service = [[ZLAppBaseService alloc] init];
service.urlStr = url;
service.params = [params mutableCopy];
[service uploadWithProgressBlock:^(NSProgress *progress, NSUInteger completedUnitCount) {
progressBlock(progress,completedUnitCount);
} finish:^(NSString *response, NSString *error) {
if (error) {
NSLog(@"Error [reqWithURL:params:finish:]\n%@",error);
finish(nil);
}else {
NSDictionary *resultDic = [ZLProtocolParser parseDictionary:response];
finish(resultDic);
}
}];
}
+ (void)reqWithURL:(NSString *)url params:(NSDictionary *)params downloadWithProgress:(void (^)(NSProgress* , NSUInteger))progressBlock finish:(void (^)(id))finish {
ZLAppBaseService *service = [[ZLAppBaseService alloc] init];
service.urlStr = url;
service.params = [params mutableCopy];
[service downloadWithProgressBlock:^(NSProgress *progress, NSUInteger completedUnitCount) {
progressBlock(progress,completedUnitCount);
} finish:^(NSString *response, NSString *error) {
if (error) {
NSLog(@"Error [reqWithURL:params:finish:]\n%@",error);
finish(nil);
}else {
NSDictionary *resultDic = [ZLProtocolParser parseDictionary:response];
finish(resultDic);
}
}];
}
#pragma mark------ 登录 ----------
+(void)reqLoginNew:(NSString *)username userpwd:(NSString *)userpwd completion:(DataHandle)dataHandle
{
NSString *token = GET_DeviceToken;
NSDictionary *params = @{
@"username" : username,
@"userpwd" : userpwd,
@"token" : token
};
[self reqWithAction:nil method:@"LoginNew" params:params methodType:@"GET" finish:^(id resultDic) {
ZLDataResult *result = [ZLProtocolParser parseArray:resultDic listName:@"Value" withClass:[ZLUserInfo class]];
dataHandle(result);
NSLog(@"登录结果=====%@",resultDic);
}];
}
@end