(OC版)总结整理下一个快速开发框架,以更优雅的方式写代码,做一个代码艺术家。分离控制器中的代码,已加入cell自适应高度,自动缓存网络请求代码,降低代码耦合,提高开发效率。
MIT License
总结整理下一个快速开发MVVM框架(抛砖引玉),主要用于分离控制器中的代码,降低代码耦合程度,可以根据自己使用习惯调整代码。欢迎来喷,提issues。代码加入了cell自适应高度,使用SMKStore缓存数据至sqlite数据库,更加高效的数据库存储库(Tip:存储自定义模型时,为了方便,数据库存储的为其转化为json后的数据,所以当读取时,请在自行转为模型即可,<利用MJExtension一行代码即可>)。
CocoaPods:
pod 'SUIMVVMKit'
@protocol SMKViewMangerProtocol <NSObject>
@optional
/**
* 设置Controller的子视图的管理者为self
*
* @param superView 一般指subView所在控制器的view
*/
- (void)smk_viewMangerWithSuperView:(UIView *)superView;
/**
* 设置subView的管理者为self
*
* @param subView 管理的subView
*/
- (void)smk_viewMangerWithSubView:(UIView *)subView;
/**
* 设置添加subView的事件
*
* @param view 管理的subView
* @param info 附带信息,用于区分调用
*/
- (void)smk_viewMangerWithHandleOfSubView:(UIView *)subView info:(NSString *)info;
/**
* 返回viewManger所管理的视图
*
* @return viewManger所管理的视图
*/
- (__kindof UIView *)smk_viewMangerOfSubView;
/**
* 得到其它viewManger所管理的subView,用于自己内部
*
* @param views 其它的subViews
*/
- (void)smk_viewMangerWithOtherSubViews:(NSDictionary *)viewInfos;
/**
* 需要重新布局subView时,更改subView的frame或者约束
*
* @param block 更新布局完成的block
*/
- (void)smk_viewMangerWithLayoutSubViews:(void (^)( ))updateBlock;
/**
* 使子视图更新到最新的布局约束或者frame
*/
- (void)smk_viewMangerWithUpdateLayoutSubViews;
/**
* 将model数据传递给viewManger
*/
- (void)smk_viewMangerWithModel:(NSDictionary * (^) ( ))dictBlock;
/**
* 处理viewBlock事件
*/
- (ViewEventsBlock)smk_viewMangerWithViewEventBlockOfInfos:(NSDictionary *)infos;
/**
* 处理ViewModelInfosBlock
*/
- (ViewModelInfosBlock)smk_viewMangerWithViewModelBlockOfInfos:(NSDictionary *)infos;
/**
* 将viewManger中的信息通过代理传递给ViewModel
*
* @param viewManger viewManger自己
* @param infos 描述信息
*/
- (void)smk_viewManger:(id)viewManger withInfos:(NSDictionary *)infos;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// 将thirdView的事件处理者代理给thirdViewManger (代理方式)
[self.thirdView smk_viewWithViewManger:self.thirdViewManger];
// self.thirdView.viewEventsBlock (block方式)
self.thirdView.viewEventsBlock = [self.thirdViewManger smk_viewMangerWithViewEventBlockOfInfos:@{@"view" : self.thirdView}];
// viewManger ----> info <----- viewModel 之间通过代理方式交互
self.thirdViewManger.viewMangerDelegate = self.viewModel;
self.viewModel.viewModelDelegate = self.thirdViewManger;
// viewManger ----> info <----- viewModel 之间通过block方式交互
self.thirdViewManger.viewMangerInfosBlock = [self.viewModel smk_viewModelWithViewMangerBlockOfInfos:@{@"info" : @"viewManger"}];
// 中介者传值
SMKMediator *mediator = [SMKMediator mediatorWithViewModel:self.viewModel viewManger:self.thirdViewManger];
self.thirdViewManger.smk_mediator = mediator;
self.viewModel.smk_mediator = mediator;
self.thirdViewManger.smk_viewMangerInfos = @{@"xxxxxx" : @"22222222"};
[self.thirdViewManger smk_notice];
NSLog(@"viewManger------>viewModel==%@", self.viewModel.smk_viewModelInfos);
self.viewModel.smk_viewModelInfos = @{@"oooooo" : @"888888888"};
[self.viewModel smk_notice];
NSLog(@"viewModel=====>viewManger==%@", self.thirdViewManger.smk_viewMangerInfos);
}
- (IBAction)clickBtnAction:(UIButton *)sender {
// thirdView 通过viewModel传递的model来配置view
[self.thirdView smk_configureViewWithViewModel:self.viewModel];
}
#pragma mark 加载网络请求
- (NSURLSessionTask *)smk_viewModelWithProgress:(progressBlock)progress success:(successBlock)success failure:(failureBlock)failure {
return [[SMKAction sharedAction] sendRequestBlock:^id<SMKRequestProtocol>{
return [[ThirdRequest alloc]init];
} progress:nil success:^(id responseObject) {
NSArray *modelArray = [ThirdModel mj_objectArrayWithKeyValuesArray:responseObject[@"books"]];
if (success) {
success(modelArray);
}
} failure:^(NSError *error) {
}];
}
- (id)getRandomData:(NSArray *)array {
u_int32_t index = arc4random_uniform((u_int32_t)10);
return array[index];
}
#pragma mark 配置加工模型数据,并通过block传递给view
- (void)smk_viewModelWithModelBlcok:(void (^)(id))modelBlock {
[self smk_viewModelWithProgress:nil success:^(id responseObject) {
if (modelBlock) {
if (self.viewModelDelegate && [self.viewModelDelegate respondsToSelector:@selector(smk_viewModel:withInfos:)]) {
[self.viewModelDelegate smk_viewModel:self withInfos:@{@"info" : @"呵呵, 你好, 我是ViewModel,我加载数据成功了"}];
}
modelBlock([self getRandomData:responseObject]);
}
} failure:nil];
}
#pragma mark ViewManger delegate
- (void)smk_viewManger:(id)viewManger withInfos:(NSDictionary *)infos {
NSLog(@"%@",infos);
}
#pragma mark ViewManger Block
- (ViewMangerInfosBlock)smk_viewModelWithViewMangerBlockOfInfos:(NSDictionary *)infos {
return ^{
NSLog(@"hello");
};
}
#pragma mark UIView的delegate方法
- (void)smk_view:(__kindof UIView *)view withEvents:(NSDictionary *)events {
NSLog(@"----------%@", events);
if ([[events allKeys] containsObject:@"jump"]) {
FirstVC *firstVC = [UIViewController sui_viewControllerWithStoryboard:nil identifier:@"FirstVCID"];
[view.sui_currentVC.navigationController pushViewController:firstVC animated:YES];
}
}
#pragma mark ViewEvents Block
- (ViewEventsBlock)smk_viewMangerWithViewEventBlockOfInfos:(NSDictionary *)infos {
return ^(NSString *info){
if (self.viewMangerInfosBlock) {
self.viewMangerInfosBlock();
}
if (self.viewMangerDelegate && [self.viewMangerDelegate respondsToSelector:@selector(smk_viewManger:withInfos:)]) {
[self.viewMangerDelegate smk_viewManger:self withInfos: @{@"info" : @"哈哈,你好ViewModel,我是viewManger,我被点击了"}];
}
// NSLog(@"%@",info);
// [view smk_configureViewWithModel:self.dict[@"model"]];
};
}
#pragma mark ViewModel delegate
- (void)smk_viewModel:(id)viewModel withInfos:(NSDictionary *)infos {
NSLog(@"%@",infos);
}
- (void)smk_requestConfigures {
self.smk_scheme = @"https";
self.smk_host = @"api.douban.com";
self.smk_path = @"/v2/book/search";
self.smk_method = SMKRequestMethodGET;
}
- (id)smk_requestParameters {
return @{@"q": @"基础"};
}
- (NSURLSessionTask *)smk_viewModelWithProgress:(progressBlock)progress success:(successBlock)success failure:(failureBlock)failure {
return [[SMKAction sharedAction] sendRequestBlock:^id<SMKRequestProtocol>{
return [[FirstRequest alloc]init];
} progress:nil success:^(id responseObject) {
if (responseObject) {
NSArray *modelArray = [FirstModel mj_objectArrayWithKeyValuesArray:responseObject[@"books"]];
success(modelArray);
}
} failure:^(NSError *error) {
}];
}