在项目中,分页加载是家常便饭。下拉,page重置,上拉,page+1,虽说也挺简单的,但是到处都需要处理page的代码,就显得有些分散和冗余。由于我自己的项目是基于离散型api设计,因此封装了一套通用分页的request,让调用者尽量不用去考虑page的变化。
BaseRequest
前面提到离散型api,简单介绍一下。首先有个BaseRequest,在里面可以设置一些通用的配置,比如token,appVersion等等,或者是超时时间。每个api都是一个request,都继承于BaseRequest。
@interface BaseRequest : NSObject
@property (nonatomic, assign) BOOL isExcuting;
@property (nonatomic, assign) RequestPolicy requestPolicy;
@property (nonatomic, strong) NSError *responseError;
@property (nonatomic, strong) id responseJSONObject;
@property (nonatomic, weak) id<RequestDelegate> delegate;
- (instancetype)initWithDelegate:(id<RequestDelegate>)delegte;
// baseurl
- (NSString *)baseUrlString;
// relative url
- (NSString *)requestUrlString;
// 组装参数
- (NSDictionary *)params;
// 默认为GET
- (RequestMethod)requestMethod;
- (RequestUploadMultiMediaBlock)constructingBodyBlock;
- (void)startRequest;
- (void)cancel;
@end
PageRequest
封装分页request,自然也是继承于baseRequest了。属性都比较清晰。
- curPage:当前page,
- PageNumber:每页拉取数,
- isLastPage:是否是最后一页,
- pageType:加载更多 or 刷新。
typedef NS_ENUM(NSInteger, PageType) {
PageNoneType,
PageRefresh,
PageLoadMore
};
@interface PageRequest : BaseRequest
@property (nonatomic) NSInteger curPage;
@property (nonatomic) NSInteger pageNumber;
@property (nonatomic) PageType pageType;
@property (nonatomic, readonly) BOOL isLastPage;
// 失败重置curPage
- (void)resetPageWhenFail;
@end
@implementation PageRequest
- (instancetype)initWithDelegate:(id<RequestDelegate>)delegte {
if (self = [super initWithDelegate:delegte]) {
_curPage = 1;
_pageNumber = PAGENUMBER;
}
return self;
}
- (BOOL)isLastPage {
if ([self.responseDataObject isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = self.responseDataObject;
NSString *next = [dict stringForKey:@"next"];
if (!next || next.length == 0) {
return YES;
}
}
return NO;
}
// 失败重置curPage
- (void)resetPageWhenFail {
if (self.pageType == PageLoadMore) {
if (self.curPage > 1) {
self.curPage--;
}
}
}
// 组装参数
- (NSDictionary *)params {
NSDictionary *baseDict = [super params];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:0];
if (baseDict) {
[dict addEntriesFromDictionary:baseDict];
}
if (self.pageType == PageRefresh) {
self.curPage = 1;
} else if (self.pageType == PageLoadMore) {
self.curPage++;
}
dict[@"offset"] = @(self.curPage);
dict[@"limit"] = @(self.pageNumber);
return dict;
}
@end
调用
比如要加载导师列表,先定义个GetMentorListRequest: PageRequest。
@implementation GetMentorListRequest
- (NSString *)requestUrlString {
return @"/mentors/";
}
// 组装参数
- (NSDictionary *)params {
NSDictionary *pageDict = [super params];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:0];
if (pageDict) {
[dict addEntriesFromDictionary:pageDict];
}
if (self.industryId) {
dict[@"industry"] = self.industryId;
}
return dict;
}
@end
在model层封装调用。注意一点,在请求失败的时候,要注意将page回置。
// 获取导师列表
- (void)getMentorList:(NSNumber *)industryId pageType:(PageType)type {
self.getMentorListRequest.industryId = industryId;
self.getMentorListRequest.pageType = type;
[self.getMentorListRequest startRequest];
}
- (void)refresh {
[self getMentorList:self.industryId pageType:PageRefresh];
}
- (void)loadMore {
[self getMentorList:self.industryId pageType:PageLoadMore];
}
#pragma mark - rsp
- (void)handleFailedResult:(BaseRequest *)request {
if ([request isKindOfClass:[GetMentorListRequest class]]) {
GetMentorListRequest *getMentorListRequest = (GetMentorListRequest *)request;
// 重置curpage
[getMentorListRequest resetPageWhenFail];
}
}
这样调用者就完全不用关心page了。对于集中型的网络请求,就需要在各自的数据管理类中记录page,然后进行更新。
当然,如果你非要自己去手动管理的话,那就这样。自己去控制page,pageNum。
- (void)getMentorList:(NSNumber *)industryId page:(NSInteger)page
pageNum:(NSInteger)pageNum {
self.getMentorListRequest.industryId = industryId;
self.getMentorListRequest.curPage = page;
self.getMentorListRequest.pageNumber = pageNum;
[self.getMentorListRequest startRequest];
}