测试已测试 | ✗ |
语言语言 | Objective-CObjective C |
许可证 | MIT |
发布日期上次发布 | 2018年6月 |
由 Ryan ChenZhiWen 维护。
FlexibleAIFNetworking 是基于 AIFNetworking 改造而成的网络框架。
AIFNetworking
和 FlexibleAIFNetworking
比较
|| AIFNetworking | FlexibleAIFNetworking
---|---|---|---
灵活性|
依赖|AFNetworking 2|AFNetworking 3
github https://github.com/czwen/RTNetworking
欢迎发送 PR,共同维护
将 pod 'FlexibleAIFNetworking'
添加到您的 Podfile,然后运行 pod install
创建一个 AIFService 类型的对象。
==命名很重要==,例如 AIFServiceMyShop
,AIFServiceTaobao
之类的。规则是以 AIFService
为前缀,后面随意。
必须符合 <AIFServiceProtocal>
协议。如果还涉及参数签名的,还可以添加 <AIFSignatureProtocol>
一般来说,一个 AIFService
代表一个 API 服务。因此无需创建多个。
创建 RTAPIBaseManager 对象。名称随意。例如 XSProductDetailAPIManager
。
符合 <RTAPIManager>
。
提供 <RTAPIManagerValidator>
用于验证参数与返回数据的正确性。
在使用的位置(ViewController)创建一个 XSProductDetailAPIManager
对象。
_productDetailApiManager.paramSource = self;
_productDetailApiManager.delegate = self;
...
[_productDetailApiManager loadData];
这样就可以完成一次请求。
RTAPIManagerParamSourceDelegate // 多用在ViewController上,用于处理请求参数
RTAPIManagerApiCallBackDelegate // 多用在ViewController上,用于处理响应
RTAPIManager // 多用在RTAPIManager上,基础
RTAPIManagerValidator // 多用在RTAPIManager上,用于检验数据,让使用者知道这个接口需要什么参数
AIFServiceProtocal // 多用在AIFService上,基础
AIFSignatureProtocol // 多用在AIFService上,用于签名
class AIFServiceMyShop
//
// AIFServiceMyShop.h
//
@interface AIFServiceMyShop : AIFService <AIFServiceProtocal>
@end
//
// AIFServiceMyShop.m
//
@implementation AIFServiceMyShop
#pragma mark - AIFServiceProtocal
- (BOOL)isOnline
{
return YES;
}
- (NSString *)onlineApiBaseUrl
{
return @"baseUrl";
}
- (NSString *)onlineApiVersion
{
return @"api/v1";
}
- (NSString *)onlinePrivateKey
{
return @"PrivateKey";
}
- (NSString *)onlinePublicKey
{
return @"PublicKey";
}
- (NSString *)offlineApiBaseUrl
{
return self.onlineApiBaseUrl;
}
- (NSString *)offlineApiVersion
{
return self.onlineApiVersion;
}
- (NSString *)offlinePrivateKey
{
return self.onlinePrivateKey;
}
- (NSString *)offlinePublicKey
{
return self.onlinePublicKey;
}
- (BOOL)onlineIsSingtureAllParamters
{
return YES;
}
- (BOOL)offlineIsSingtureAllParamters
{
return YES;
}
- (NSDictionary *)serviceHeadersDictionary
{
NSMutableDictionary *headerDic = [NSMutableDictionary dictionary];
[headerDic setValue:@"application/json" forKey:@"Accept"];
[headerDic setValue:@"application/x-www-form-urlencoded" forKey:@"Content-Type"];
NSDictionary *loginResult = [[NSUserDefaults standardUserDefaults] objectForKey:@"______"];
if (loginResult[@"token"]) {
[headerDic setValue:loginResult[@"token"] forKey:@"token"];
}
return headerDic;
}
- (NSDictionary *)serviceCommonParamsDictionary
{
return @{
// 例如手机版本之类的信息
};
}
@end
class XSProductDetailAPIManager
//
// XSProductDetailAPIManager.h
//
@interface XSProductDetailAPIManager : RTAPIBaseManager<RTAPIManager,RTAPIManagerValidator>
@end
//
// XSProductDetailAPIManager.m
//
@interface XSProductDetailAPIManager()
@property (nonatomic, strong) NSString *gid;
@end
@implementation XSProductDetailAPIManager
- (instancetype)init{
self = [super init];
if (self) {
self.validator = self;
}
return self;
}
- (NSString *)serviceType
{
// 上面说到定义Service名字的重要性在于
// 每个APIManager 都要有一个所归属的Service
return @"MyShop";
}
- (NSString *)methodName
{
return [NSString stringWithFormat:@"goods/%@",self.gid];
}
- (RTAPIManagerRequestType)requestType
{
return RTAPIManagerRequestTypeGet; // 支持GET POST PUT DEL
}
- (BOOL)manager:(RTAPIBaseManager *)manager isCorrectWithParamsData:(NSDictionary *)data{
// 用于校验参数的正确性
return YES;
}
- (BOOL)manager:(RTAPIBaseManager *)manager isCorrectWithCallBackData:(NSDictionary *)data{
// 用于校验响应数据的正确性
return YES;
}
- (NSDictionary *)reformParams:(NSDictionary *)params{
// 处理ParamsSorce的参数。
// 请求前都会先到这里。
// 由于这个接口是采用 url+id 方式。
// 本身AIFNetworking 也没有这么情况。所以我就采取一些小技巧来实现了。
// reform 之后的参数 依然会调用
// - (BOOL)manager:(RTAPIBaseManager *)manager isCorrectWithParamsData:(NSDictionary *)data;
self.gid = params[kProductDetailID];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:params];
[dic removeObjectForKey:kProductDetailID];
return dic;
}
#pragma mark
#pragma mark - public method
// 能获取到APIManager 对象的地方就能调用 loadData 方法。
// 参数永远从 <RTAPIManagerParamSourceDelegate> 里获取。
// 所以每个请求的地方都不用关心参数的问题。
// 返回值是一个request ID。可以通过request ID取消某一个请求。
// 注意 APIManager 不是只有一个请求,同一 APIManager 可以产生很多请求。
- (NSInteger)loadData;
class ViewController
//
// ViewController.m
//
@interface ViewController()
<
RTAPIManagerParamSourceDelegate,
RTAPIManagerApiCallBackDelegate,
>
>
@property (nonatomic, strong) XSProductDetailAPIManager *productDetailApiManager;
@end
@implementation XSProductDetailViewController
- (void)viewDidLoad{
[super viewDidLoad];
[self.productDetailApiManager loadData]; // 发起请求
}
- (XSProductDetailAPIManager *)productDetailApiManager
{
if (!_productDetailApiManager) {
_productDetailApiManager = [[XSProductDetailAPIManager alloc] init];
_productDetailApiManager.paramSource = self;
_productDetailApiManager.delegate = self;
}
return _productDetailApiManager;
}
#pragma mark
#pragma mark - RTAPIManagerParamSourceDelegate
- (NSDictionary *)paramsForApi:(RTAPIBaseManager *)manager{
return @{
@"good_id":self.goodsId
};
}
#pragma mark
#pragma mark - RTAPIManagerParamSourceDelegate
- (void)managerCallAPIDidSuccess:(RTAPIBaseManager *)manager{
// success callback
[manager fetchDataWithReformer:self.bottomView];
}
- (void)managerCallAPIDidFailed:(RTAPIBaseManager *)manager{
// failed callback
}
@end
#### 至此,您已经可以使用 FlexibleAIFNetworking
发起请求了。
在 APIManager 中实现分页功能,可以使用以下 3 个方法。
- (void)beforePerformSuccessWithResponse:(AIFURLResponse *)response
- (void)beforePerformFailWithResponse:(AIFURLResponse *)response
- (NSDictionary *)reformParams:(NSDictionary *)params
- (void)beforePerformSuccessWithResponse:(AIFURLResponse *)response
{
self.totalPage = [response.content[@"data"][@"pagination"][@"total"] integerValue];
self.nextPage = self.requestPage+1;
if (self.nextPage >= self.totalPage) {
self.isLoadedLastPage = YES;
}
}
- (void)beforePerformFailWithResponse:(AIFURLResponse *)response
{
// 如果没有使用一个变量 requestPage 来记录请求的页数,直接在self.nextPage 上增加
// 失败时需要恢复 self.nextPage--
}
- (NSDictionary *)reformParams:(NSDictionary *)params
{
NSMutableDictionary *p = [NSMutableDictionary dictionaryWithDictionary:params];
[p addEntriesFromDictionary:@{
@"page":@(self.requestPage).stringValue
}];
return p;
}
// 自己定义的方法
- (NSInteger)loadFirstPage
{
if (self.isLoading) {
[self cancelAllRequests];
}
self.isLoadedLastPage = NO;
self.requestPage = 1;
return [self loadData];
}
- (NSInteger)loadNextPage
{
if (self.isLoading || self.isLoadedLastPage) {
return NSNotFound;
}
self.requestPage = self.nextPage;
return [self loadData];
}
<RTAPIManagerCallbackDataReformer>
将数据交给使用者处理,由使用者自己选择需要什么样的数据。或者不适用于大多数项目。另外还涉及到 去Model化
。
如果以上内容未能满足您,可以到原作者 https://github.com/casatwy/RTNetworking 页面克隆下来,上面有 keynote,介绍这个框架的设计……之类的干货。