前言
最近,结合公司的项目,在前人的基础上整理了一个Framework的一个东西,主要包含了一些常用的category
整理; model
基类的使用,基于MJExtension
实现一个model
基类,模型数据的使用可以继承该基类;网络请求的使用,对于 AFNetworking
的封装,可实现数据请求和网络下载;第三方分享的封装,可以直接使用,分享到QQ,微信, 微博;View的一些使用,1)UITableView和UICollectionView的封装使用,实现UITableView和UICollectionView的上拉刷新和下拉加载(PS:不是三方的刷新和加载)2)自定义的TabBar;UIViewController的使用,实现一个基类的ViewController,实现相关的属性设置,VC的使用继承该基类;还有一些帮助类的使用。FFFramework暂不支持Cocopods。
项目结构介绍
具体使用
- Category
Category里面主要是一些常用分类,比如设备类型,文件管理,日期设置,颜色处理和图片处理等,没什么值得具体说的,具体用的时候直接拿来用就可以了。附张图看一眼吧:
- Models
Model里面会有一个叫做FFBaseModel
的基类,凡是关于模型数据的都可以集成该基类。如图:
用法也很简单,是基于MJExtension
,和 MIExtension
的使用是一致的,只不过在外层包装了一下而已。支持字典转模型,字典数组转模型数组, 模型数组转字典数组等。下面是一些常用方法:
@interface FFBaseModel : NSObject
- (NSDictionary *)ff_toKeyValue;
- (void)ff_modelsDidFinishConvertingToKeyValues;
- (void)ff_keyvaluesDidFinishConvertingToModels;
// 属性名替换
+ (NSDictionary *)ff_replaceKeyFromPropertyName;
+ (NSDictionary *)ff_objectClassInArray;
// 可忽略的属性名
+ (NSArray *)ff_ignoredPropertyNames;
// 字典转模型
+ (instancetype)ff_modelFromKeyValue:(NSDictionary *)keyValue;
+ (NSArray *)ff_keyValuesFromModels:(NSArray *)models;
// 字典数组转模型数组
+ (NSArray *)ff_modelsFromKeyValues:(NSArray *)keyvalues;
+ (NSArray *)ff_allowedCodingPropertyNames;
+ (NSArray *)ff_ignoredCodingPropertyNames;
@end
- Network
Network里面包含网络数据的请求和上传,以及网络数据下载,基于AFNetworking
对AFNetworking
的封装使用,包括 FFBaseRequest
和 FFBaseDownloadRequest
, 如下:
1) 先看 FFBaseRequest.h
文件
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@class FFBaseRequest;
typedef NS_ENUM(NSUInteger, FFRequestMethod) {
FFRequestMethodGet,
FFRequestMethodPost,
FFRequestMethodPut,
FFRequestMethodDelete
};
typedef NS_ENUM(NSInteger, FFNetworkReachabilityStatus) {
FFNetworkReachabilityStatusUnknown = -1,
FFNetworkReachabilityStatusNotReachable = 0,
FFNetworkReachabilityStatusReachableViaWWAN = 1,
FFNetworkReachabilityStatusReachableViaWiFi = 2,
};
typedef NS_ENUM(NSUInteger, FFRequestError) {
FFRequestErrorNetwork = 0
};
static NSString *Key_Model = @"Key_Model";
typedef void(^reqSuccessBlock)(FFBaseRequest *request);
typedef void(^reqCancelBlock)(FFBaseRequest *request);
typedef void(^reqFailureBlock)(FFBaseRequest *request, NSError *error);
typedef void(^reqUploadBlock)(FFBaseRequest *request, NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite);
@interface FFBaseRequest : NSObject
/**请求路径*/
@property (nonatomic, copy, readonly) NSString *requestUrl;
/**请求参数*/
@property (nonatomic, strong, readonly) NSDictionary *requestParameters;
/**上传二进制数据数组*/
@property (nonatomic, strong, readonly) NSMutableArray *binaryParameterArray;
/**返回字典数据*/
@property (nonatomic, strong, readonly) NSMutableDictionary *resultDict;
/**结果数组*/
@property (nonatomic, strong, readonly) NSMutableArray *resultArray;
/**结果字符串*/
@property (nonatomic, copy) NSString *resultString;
@property (nonatomic, strong, readonly) UIImage *responseImage;
/**是否请求成功*/
@property (nonatomic, assign, readonly) BOOL isSuccess;
/**
* 网络数据请求
*
* @param parameters 上传参数
* @param successBlock 成功回调
* @param cancelBlock 取消回调
* @param failureBlock 失败回调
*/
+ (void)requestParameters:(NSDictionary *)parameters
successBlock:(reqSuccessBlock)successBlock
cancelBlock:(reqCancelBlock)cancelBlock
failureBlock:(reqFailureBlock)failureBlock;
/**
* 执行请求
*
* @param parameters 请求参数(非二进制文件)
* @param binaryArray 上传的二进制文件(ZZBinaryData对象)
* @param successBlock 成功回调
* @param cancelBlock 取消回调
* @param failureBlock 失败回调
* @param uploadProcessBlock 上传进度回调
*/
+ (void)requestParameters:(NSDictionary *)parameters
binaryArray:(NSMutableArray *)binaryArray
successBlock:(reqSuccessBlock)successBlock
cancelBlock:(reqCancelBlock)cancelBlock
failureBlock:(reqFailureBlock)failureBlock
uplodProcessBlock:(reqUploadBlock)uploadProcessBlock;
/**获取请求地址*/
- (NSString *)getRequestUrl;
/// 是否正在请求数据
+ (BOOL)isRequesting;
/**获取当前网络类型*/
+ (FFNetworkReachabilityStatus)fetchReachabilityStatus;
/**启动网络监听*/
+ (void)starNetWorkReachability;
#pragma mark - Children Class
- (NSString *)getRequestHost;
- (NSString *)getRequestQuery;
- (NSString *)getUserAgent;
/**请求头设置*/
- (NSDictionary<NSString *, NSString *> *)getCustomHeaders;
/**请求方式(默认GET)*/
- (FFRequestMethod)getRequestMethod;
/**请求参数*/
- (NSDictionary *)getDefaultParameters;
/**数据解析*/
- (void)processResult;
/**取消请求*/
+ (void)cancelTheRequest;
#pragma mark- 以下可根据服务器返回自行设置
/**是否成功*/
- (BOOL)success;
/**请求失败错误信息*/
- (NSString *)errorMsg;
/**数据总数*/
- (NSInteger)totalCount;
/**是否有数据(通常是分页请求数据)*/
- (BOOL)hasMoreData;
@end
已有相关的注释,具体查看可以看源项目, 我会在最后把地址贴一下,现在结合一个接口, 看一下具体使用,一般数据请求和UITableView连用,我一起贴出来了:
首先,继承FFBaseRequest
创建一个通用请求类 TestRequest
#import "FFBaseRequest.h"
extern NSString * const FORMAL_SERVER_URL;
extern NSString * const TEST_SERVER_URL;
@interface TestRequest : FFBaseRequest
@end
/*******************************************/
#import "TestRequest.h"
// 以豆瓣的接口为例
NSString * const FORMAL_SERVER_URL = @"https://api.douban.com/v2/"; // 正式服务器
NSString * const TEST_SERVER_URL = @"https://api.douban.com/v2/"; // 测试服务器
@implementation TestRequest
#pragma mark - Methods
// 设置getRequestHost的目的是为了方便,如:https://api.douban.com/v2/book/search?q=“美女”&start = 0&count = 20 这个地址,https://api.douban.com/v2/ 这是通用的,可单独提取出来,如针对图书相关的接口,将book/search?q=“美女”&start = 0&count = 20拼起来即可。
- (NSString *)getRequestHost {
return FORMAL_SERVER_URL;
// return TEST_SERVER_URL;
}
- (BOOL)isSuccess {
return [self success];
}
- (BOOL)success {
if ([self.resultDict.allKeys containsObject:@"status"]) {
NSDictionary *dict = self.resultDict[@"status"];
NSInteger code = [[NSString stringWithFormat:@"%@", dict[@"code"]] integerValue];
return code == 1;
}
return false;
}
- (NSString *)errorMsg {
if ([self.resultDict.allKeys containsObject:@"status"]) {
NSDictionary *dict = self.resultDict[@"status"];
return dict[@"msg"];
}
return @"";
}
#pragma mark - 可根据具体返回数据设置相关属性
- (NSInteger)totalCount {
return [self.resultDict[@"total"] integerValue];
}
@end
接着,以豆瓣的图书搜索为例,继承 TestRequest
创建一个图书搜索请求 TestARequest
/**
获取书籍信息的接口
*/
/**
GET https://api.douban.com/v2/book/search
参数 意义 备注
q 查询关键字 q和tag必传其一
tag 查询的tag q和tag必传其一
start 取结果的offset 默认为0
count 取结果的条数 默认为20,最大为100
返回:返回status=200,
{
"start": 0,
"count": 10,
"total": 30,
"books" : [Book, ]
}
*/
#import "TestRequest.h"
@interface TestARequest : TestRequest
@end
/*******************************************/
#import "TestARequest.h"
#import "TestModel.h" // 图书模型
@implementation TestARequest
// https://api.douban.com/v2/book/search?q=“美女”&start = 0&count = 20, https://api.douban.com/v2/ 已提取出来, 由于q=“美女”&start = 0&count = 20中 q ,start, count 可能会有改变,故不能写死, 在 getRequestQuery方法中拼接book/search? 即可。
- (NSString *)getRequestQuery {
return @"book/search?";
}
// 进行数据解析,字典数组转模型
- (void)processResult {
NSArray *results = self.resultDict[@"books"];
NSArray *books = [TestModel ff_modelsFromKeyValues:results];
if (books != nil) {
[self.resultDict setObject:books forKey:Key_Model];
}
}
准备工作已完成,下面就在ViewController里面请求数据:
// 下拉刷新和上拉加载可先忽略
- (void)getNetData:(BOOL)isRefresh {
if ([TestARequest isRequesting]) {
return;
}
__weak typeof(self) WS = self;
NSInteger page = isRefresh ? 1 : _page + 1;
NSDictionary *parameter = @{@"q": @"美女",
@"start": @(page),
@"count": @20};
// 1.设置下拉刷新 (不需要的话可去掉)
id refreshBlock = ^{
[WS getNetData:YES];
};
[self.tableView setRefreshBlock:refreshBlock];
// 回调成功Block
id successBlock = ^(FFBaseRequest *request){
NSLog(@"请求路径-->> %@",request.requestUrl); // 这时请求路径就是一个完成的地址了。
NSLog(@"请求参数-->> %@",request.requestParameters);
NSLog(@"请求结果-->> %@",request.resultDict);
// 2.设置分页数
_page = page;
// 3.获取数据
NSArray *arrResult = request.resultDict[Key_Model];
if (isRefresh) {
WS.books = arrResult;
} else {
NSMutableArray *arrTemp = [NSMutableArray arrayWithArray:WS.books];
[arrTemp addObjectsFromArray:WS.books];
WS.books = arrTemp;
}
// 4.设置上拉加载(不需要可去掉)
id moreBlock = ^ {
[WS getNetData:NO];
};
[WS.tableView setMoreBlock:request.totalCount > WS.books.count ? moreBlock : nil];
// 5.完成加载
[WS.tableView didFinishedLoading];
// 6.数据刷新
[WS.tableView reloadData];
};
// 回调取消Block
id cancleBlock = ^(FFBaseRequest *request) {
[WS.tableView didFinishedLoading];
};
// 回调失败Block
id failureBlock = ^(FFBaseRequest *request, NSError *error){
[WS.tableView didFinishedLoading];
NSLog(@"---> %@",error.localizedDescription);
};
[TestARequest requestParameters:parameter successBlock:successBlock cancelBlock:cancleBlock failureBlock:failureBlock];
}
到此,一个数据请求就算完成了,这样更加模块化,更加好维护。。。。
2) 接着看FFBaseDownloadRequest.h
#import <Foundation/Foundation.h>
@class FFBaseDownloadRequest;
extern NSString * const FFDownloadErrorReasonKey;
extern NSString * const FFDownloadDoDownloadBlockKey;
extern NSString * const FFDownloadAllowUseMobileNetworkKey;
extern NSString * const FFDownloadAllowUseMobileNetworkNotification;
typedef void(^ProgressBlock)(float progress, NSUInteger bytesRead, unsigned long long totalRead, unsigned long long totalExpectedToRead);
typedef void(^SuccessBlock)(FFBaseDownloadRequest *request, id responseObject);
typedef void(^CancelBlock)(FFBaseDownloadRequest *request);
typedef void(^FailureBlock)(FFBaseDownloadRequest *request, NSError *error);
@interface FFBaseDownloadRequest : NSObject
/**
* 下载路径(文件夹)
*/
@property (nonatomic, strong, readonly) NSString *downloadPath;
@property (nonatomic, strong, readonly) NSString *fileName;
/**
* 下载文件绝对路径
*/
@property (nonatomic, strong, readonly) NSString *filePath;
/**
* 下载文件
*
* @param URLStirng 文件链接
* @param fileName 文件名
* @param progressBlock 下载进度回调
* @param successBlock 下载成功回调
* @param failureBlock 下载失败回调
*
* @return 下载任务
*/
+ (FFBaseDownloadRequest *)downloadFileWithURLString:(NSString *)URLStirng
fileName:(NSString *)fileName
progressBlock:(ProgressBlock)progressBlock
successBlock:(SuccessBlock)successBlock
cancelBlock:(CancelBlock)cancelBlock
failureBlock:(FailureBlock)failureBlock;
/**
* 下载文件
*
* @param URLStirng 文件链接
* @param fileName 文件名
* @param downloadPath 下载位置
* @param progressBlock 下载进度回调
* @param successBlock 下载成功回调
* @param failureBlock 下载失败回调
*
* @return 下载任务
*/
+ (FFBaseDownloadRequest *)downloadFileWithURLString:(NSString *)URLStirng
downloadPath:(NSString *)downloadPath
fileName:(NSString *)fileName
progressBlock:(ProgressBlock)progressBlock
successBlock:(SuccessBlock)successBlock
cancelBlock:(CancelBlock)cancelBlock
failureBlock:(FailureBlock)failureBlock;
/**
* 暂停下载文件
*
* @param downloadRequest 下载任务
*/
+ (void)pauseWithDownloadRequest:(FFBaseDownloadRequest *)downloadRequest;
/**
* 恢复下载文件
*
* @param downloadRequest 下载请求
*/
+ (void)resumeWithDownloadRequest:(FFBaseDownloadRequest *)downloadRequest;
/**
* 获取文件大小
*
* @param path 本地路径
*
* @return 文件大小
*/
- (unsigned long long)fileSizeForPath:(NSString *)path;
/**
* 暂停下载
*/
- (void)pauseDownload;
/**
* 恢复下载
*/
- (void)resumeDownload;
/**
* 取消下载
*/
- (void)cancelDownload;
/**
* 是否正在下载
*/
- (BOOL)isDownloading;
/**
* 是否完成
*/
- (BOOL)finished;
/**
* 移除Cache
*/
+ (void)removeAllCache;
网络数据下载,简单使用 :
- (void)downloadData {
// http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.5.1.dmg
NSString *path = [kCachePath stringByAppendingPathComponent:@"QQ"];
if (![NSFileManager isDirectoryExist:path]) {
[NSFileManager createDirectorysAtPath:path];
}
[FFBaseDownloadRequest downloadFileWithURLString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.5.1.dmg" downloadPath:path fileName:[NSString stringWithFormat:@"%@", @"1.zip"] progressBlock:^(float progress, NSUInteger bytesRead, unsigned long long totalRead, unsigned long long totalExpectedToRead) {
NSLog(@"---------->> %f", progress);
} successBlock:^(FFBaseDownloadRequest *request, id responseObject) {
NSLog(@">> %@",request.filePath);
} cancelBlock:^(FFBaseDownloadRequest *request) {
} failureBlock:^(FFBaseDownloadRequest *request, NSError *error) {
NSLog(@" ---->> %@",error.localizedDescription);
}];
}
- ShareKit
ShareKit里面包含分享都QQ,微信,微博 第三方平台,傻瓜式分享,只需要申请相对应的AppKey 和 AppSecretKey,设置好相关的白名单,就能实现分享啦~~。
下面我们来看看简单使用:
ShareContentInfo
类设置分享信息,包含分享的类型(文字,链接等)
#import "FFBaseModel.h"
#import "FFAuthInfo.h"
typedef NS_ENUM(NSUInteger, ShareContentType) {
ShareContentType_None,
ShareContentType_Text,
ShareContentType_Link,
ShareContentType_Image
};
@interface ShareContentInfo : FFBaseModel
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, strong) NSString *urlStr;
@property (nonatomic, strong) NSString *imgPath;
@property (nonatomic, strong) NSData *objData;
@property (nonatomic, assign) ShareContentType contentType;
@property (nonatomic, assign) ShareType shareType;
/**
* 获取分享信息
*
* @param title 标题
* @param content 内容
* @param contentType 分享的类型
* @return ShareContentInfo
*/
+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content contentType:(ShareContentType)contentType;
/**
* 获取分享信息
*
* @param title 标题
* @param content 内容
* @param url 链接
* @param imgPath 图片地址
* @param contentType 分享的类型
* @return ShareContentInfo
*/
+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content url:(NSString *)url imagePath:(NSString *)imgPath contentType:(ShareContentType)contentType;
/**
* 获取分享信息
*
* @param title 标题
* @param content 内容
* @param url 链接
* @param imgPath 图片地址
* @param objData 图片二进制文件
* @param contentType 分享的类型
* @return ShareContentInfo
*/
+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content url:(NSString *)url imagePath:(NSString *)imgPath objData:(NSData *)objData contentType:(ShareContentType)contentType;
FFBaseShareCenter
类设置分享:
typedef void(^ShareSuccessBlock)();
typedef void(^ShareCancelBlock)(BOOL cancelled);
typedef void(^ShareFailureBlock)(NSError *error);
typedef NS_ENUM(NSUInteger, InstallClientType) {
InstallClientType_None,
InstallClientType_QQ,
InstallClientType_QZone,
InstallClientType_Both_QQ_QZone,
InstallClientType_Weibo,
InstallClientType_WeChat
};
typedef enum : NSUInteger {
SourceAppTypeUnknow,
SourceAppTypeQQ,
SourceAppTypeWX,
SourceAppTypeWB,
} SourceAppType;
extern NSString * const ErrorDescKey;
extern NSString * const QQAppIdKey;
extern NSString * const SinaAppIdKey;
extern NSString * const SinaRedirectURIKey;
extern NSString * const WeChatAppIdKey;
extern NSString * const WeChatAppSecretKey;
@interface FFBaseShareCenter : NSObject
@property (nonatomic, strong) FFUser *user;
@property (nonatomic, strong) FFAuthInfo *authInfo;
@property (nonatomic, strong, readonly) NSDictionary *AppIdDict;
@property (nonatomic, assign, readonly, getter=isInstalledClient) InstallClientType installedClient;
- (void)openClientAuthWithShareType:(ShareType)shareType successBlock:(ShareSuccessBlock)shareSuccessBlock cancelBlock:(ShareCancelBlock)shareCancelBlock failureBlock:(ShareFailureBlock)shareFailureBlock;
+ (SourceAppType)sourceAppTypeWithSourceAppString:(NSString *)sourceApplication;
/**
在appDelegate,- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 里面实现该方法
*/
+ (BOOL)handlerOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication;
/**
* 设置各平台的AppId、AppSecret、RedirectURI
*
* @param appIdDict key 为QQAppIdKey,SinaAppIdKey,WeChatAppIdKey value 为各平台AppId
* @param appSecretDict key 为WeChatAppSecretKey,... value为各平台的Secret
* @param redirectURIDict key 为SinaRedirectURIKey,... value为各平台的RedirectURI
*/
+ (void)setAppId:(NSDictionary *)appIdDict appSecret:(NSDictionary *)appSecretDict redirectURI:(NSDictionary *)redirectURIDict;
/**
* 获取分享平台
*
* @param shareType 分享类型
* @return 分享平台
*/
+ (FFBaseShareCenter *)getShareCenterWithShareType:(ShareType)shareType;
/**
* 分享
*
* @param contentInfo 分享信息
* @param successBlock 成功回调
* @param cancelBlock 取消回调
* @param failureBlock 失败回调
*/
- (void)shareContentInfo:(ShareContentInfo *)contentInfo successBlock:(ShareSuccessBlock)successBlock cancelBlock:(ShareCancelBlock)cancelBlock failureBlock:(ShareFailureBlock)failureBlock;
- (void)executeFailureBlock:(ShareFailureBlock)failureBlock errorDomain:(NSString *)ErrorDomain errorMsg:(NSString *)errorMsg errorCode:(NSInteger)errorCode;
简单使用,如下:
- (IBAction)onShareBtnTap:(UIButton *)sender {
UIImage *image = [UIImage imageNamed:@"benz.png"];
NSData *imgData = UIImagePNGRepresentation(image);
ShareContentInfo *shareInfo = [ShareContentInfo shareTitle:@"哈哈哈" content:@"你在干什么,什么都不说" url:@"https:www.baidu.com" imagePath:nil objData:imgData contentType:ShareContentType_Link];
ShareType shareType = ShareType_None;
if (sender.tag == 1) {
shareType = ShareType_WeChat;
} else if (sender.tag == 2) {
shareType = ShareType_QQ;
} else if (sender.tag == 3) {
shareType = ShareType_WeChatTimeline;
} else if (sender.tag == 4) {
shareType = ShareType_Sina;
}
shareInfo.shareType = shareType;
FFBaseShareCenter *shareCenter = [FFBaseShareCenter getShareCenterWithShareType:shareType];
[shareCenter shareContentInfo:shareInfo successBlock:^{
NSLog(@"分享成功");
} cancelBlock:^(BOOL cancelled) {
NSLog(@"取消分享");
} failureBlock:^(NSError *error) {
NSLog(@"分享失败 --->%@",error.localizedDescription);
}];
}
- ViewController
ViewController创建了一个基类,使用VC的时候都可以继承该基类,可设置标题,NavigationBar的设置, 如下:
@interface FFBaseViewController : UIViewController
/**设置标题*/
@property (nonatomic, copy) NSString *navigationTitle;
/**设置标题颜色*/
@property (nonatomic, strong) UIColor *navigationTitleColor;
/**设置NavigationBar颜色*/
@property (nonatomic, strong) UIColor *navigationBarColor;
/**隐藏NavigationBar*/
@property (nonatomic, assign, getter=isHideNavigationBar) BOOL hideNavigationBar;
/**隐藏状态栏*/
@property (nonatomic, assign, getter=isHideStatusBar) BOOL hideStatusBar;
/**设置状态栏样式*/
@property (nonatomic, assign, getter=isStatusBarStyleDefault) BOOL statusBarStyleDefault;
@property (nonatomic, assign, getter=isNavBarColorChange) BOOL navBarColorChange;
/**左按钮*/
@property (nonatomic, strong) UIButton *leftBtn;
/**右按钮*/
@property (nonatomic, strong) UIButton *rightBtn;
/**右边多个按钮数组*/
@property (nonatomic, strong) NSArray *rightBtns;
/***/
@property (nonatomic, copy) DismissBlock dismissBlock;
/**显示返回按钮(默认返回按钮)*/
- (void)showBackBtn;
/**返回按钮点击*/
- (void)onBackBtnTap:(UIButton *)sender;
/**取消请求*/
- (void)cancelAllRequest;
+ (NSString *)classStr;
- View
View里面包含自定义 UITableView
和 UICollectionView
的使用,内封装下拉刷新和上拉加载的使用。
上面介绍了UITableView的使用,包括下拉刷新和上拉加载,这里介绍一下UICollectionView的使用。
- (void)getRequest:(BOOL) isRefresh {
if ([TestARequest isRequesting]) {
return;
}
__weak typeof(self) WS = self;
NSInteger page = isRefresh ? 1 : _page + 1;
NSDictionary *parameter = @{@"q": @"美女",
@"start": @(page),
@"count": @10};
// 回调成功Block
id successBlock = ^(FFBaseRequest *request){
// 设置分页数
_page = page;
// 获取数据
NSArray *arrResult = request.resultDict[Key_Model];
if (isRefresh) {
WS.books = arrResult;
} else {
NSMutableArray *arrTemp = [NSMutableArray arrayWithArray:WS.books];
[arrTemp addObjectsFromArray:WS.books];
WS.books = arrTemp;
}
// 设置上拉加载
[WS.collectionView isDisplayMoreView:WS.books.count < request.totalCount];
// 完成加载
[WS.collectionView didFinishedLoading];
// 刷新数据
[WS.collectionView reloadData];
};
// 回调取消Block
id cancleBlock = ^(FFBaseRequest *request) {
[WS.collectionView didFinishedLoading];
};
// 回调失败Block
id failureBlock = ^(FFBaseRequest *request, NSError *error){
[WS.collectionView didFinishedLoading];
};
[TestARequest requestParameters:parameter successBlock:successBlock cancelBlock:cancleBlock failureBlock:failureBlock];
}
// 需要实现的两个协议方法
#pragma mark - FFCollectionViewDelegate
- (void)collectionViewLoadMore:(FFCollectionView *)collectionView {
[self getRequest:NO];
}
- (void)collectionViewRefresh:(FFCollectionView *)collectionView {
[self getRequest:YES];
}
结语
到这里,基本上FFFramework的基本使用算是差不多了,具体的详细使用可以把源项目下载下来具体的试验一下。洋洋洒洒的写了这一些,算是一种总结归纳吧。。。 希望在总结的同时对别人也能有帮助。 另外, 附上源项目的地址: https://github.com/ismilesky/FFDemo.git
未完待续, 会持续补充。。。。。