Latest 0.5.2
Homepage https://github.com/lovemo/MVVMFramework
License MIT
Platforms ios 7.0, requires ARC
Frameworks CoreFoundation, Foundation, UIKit
Authors

MVVMFramework

Swift版本地址:https://github.com/lovemo/MVVMFramework-Swift

本项目交流群:474292335

欢迎有兴趣的有好的想法的参与到项目中来

Tip:SMKStore是在YTKKeyValueStore的基础上直接增加了很多的相关功能函数,(偷懒:smile:)

====

具体实现思路,请参看博客:

博客:浅谈MVVM

地址:点击链接进入

====

总结整理下一个快速开发MVVM框架(抛砖引玉),主要用于分离控制器中的代码,降低代码耦合程度,可以根据自己使用习惯调整代码。欢迎来喷,提issues。代码加入了cell自适应高度,使用SMKStore缓存数据至sqlite数据库,更加高效的数据库存储库(Tip:存储自定义模型时,为了方便,数据库存储的为其转化为json后的数据,所以当读取时,请在自行转为模型即可,<利用MJExtension一行代码即可>)。

====

usage:

CocoaPods:

    pod 'SUIMVVMKit'
  • 详细用法,请参看demo

====

思维流程图示

image
image

现在的工程代码结构

image

模块构建


结构分析


代码示例

部分protocol定义

@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

Controller中的代码


- (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];

}

配置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");
    };
}

配置viewManger

#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);
}

配置Request模型


- (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": @"基础"};
}

SMKAction发送网络请求

- (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) {

    }];

}

demo效果

  • 只需实现加载请求以及配置自定义cell和上述代码,就能轻松实现以下效果,最重要的是代码解耦。

image

期待

  • 如果在使用过程中遇到BUG,希望你能Issues我,谢谢(或者尝试下载最新的代码看看BUG修复没有)
  • 如果在使用过程中发现功能不够用,希望你能Issues我,我非常想为这个框架增加更多好用的功能,谢谢

推荐

应用架构文章

MVVM学习文章

Latest podspec

{
    "name": "SUIMVVMKit",
    "version": "0.5.2",
    "summary": "SUIMVVMKit is a MVVM frameWork easy to develop iOS",
    "homepage": "https://github.com/lovemo/MVVMFramework",
    "platforms": {
        "ios": "7.0"
    },
    "license": "MIT",
    "authors": {
        "lovemo": "[email protected]"
    },
    "source": {
        "git": "https://github.com/lovemo/MVVMFramework.git",
        "tag": "0.5.2"
    },
    "requires_arc": true,
    "public_header_files": "SUIMVVMKit/**/*.h",
    "source_files": "SUIMVVMKit/SUIMVVMKit.h",
    "frameworks": [
        "CoreFoundation",
        "Foundation",
        "UIKit"
    ],
    "subspecs": [
        {
            "name": "SUIMVVMKit",
            "requires_arc": true,
            "libraries": "sqlite3",
            "dependencies": {
                "AFNetworking": [],
                "FMDB": [],
                "SUIUtils": []
            },
            "source_files": "SUIMVVMKit/SUIMVVMKit/**/*",
            "public_header_files": "SUIMVVMKit/SUIMVVMKit/**/*.h"
        }
    ]
}

Pin It on Pinterest

Share This