IOS项目架构分享

1、项目分层:通过过往的一些项目经验,我们在IOS项目架构时候可以对项目进行如下图层:

OpenSourceSDK,顾名思义,就是我们引入的一些第三方的开源工具,比如github上开源项目

MySDK 就是我们自己封装的一些SDK。可以在各个项目中能用的

需要重点介绍的就是我们的MVP结构,请接着往下看

-----------------------------------------------------------------------------------------------------------------------

2、MVC与MVP区别一些看法:

1、在Anodrid项目结构上,经常听到MVC MVP的概念,两者的区别很明显,在MVP中M和V是不通信的。

2、在IOS平台上,身边的IOS开发朋友很少提到MVP,网上查找的资料也很少有把MVP和IOS关联在一起的。

3、查阅了一些资料,IOS上的MVC,M和V之间就是不通信的。这点在讨论Anodrid上是不同的。其实,MVC也好MVP也好,只是一个说法。不用太纠结。重要的是我们在项目中要知道M和V要解耦。

以下引用网上的两张图片,可以帮更好的理解

更多MVP,MVC讨论请点击链接:

MVP MVC的认识http://blog.csdn.net/sbvfhp/article/details/47848403

-----------------------------------------------------------------------------------------------------------------------

3、我自己项目的结构图如下(有更好的意见请大家指出)

-----------------------------------------------------------------------------------------------------------------------

4、MVP里需要重点考虑的问题

Controller需要考虑的重点:
对View 和 Model之间的一个协调,调度。

以下是一个列表的显示(包含下拉刷新,加载更多),核心代码也就几十行。

[objc] 
view plain
copy

  1. @interface  WorksViewController () {
  2. IBOutlet UICollectionView *_collectionView;
  3. WorksRequest *_worksRequest;
  4. NSInteger _page;
  5. BOOL _isEnd;
  6. NSMutableArray *_data;
  7. }
  8. @end
  9. @implementation WorksViewController
  10. - (void)viewDidLoad {
  11. [super viewDidLoad];
  12. [_collectionView registerNib:[UINib nibWithNibName:@"WorksCell" bundle:nil] forCellWithReuseIdentifier:@"WorksCell"];
  13. _data = [NSMutableArray new];
  14. _worksRequest = [[WorksRequest alloc]init];
  15. _collectionView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
  16. [self refresh];
  17. }];
  18. _collectionView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
  19. [self loadMore];
  20. }];
  21. [_collectionView.header beginRefreshing];
  22. }
  23. -(void)clean {
  24. for (WorksDB *worksDB in _data) {
  25. [worksDB MR_deleteEntity];
  26. }
  27. [[NSManagedObjectContext MR_defaultContext]MR_saveToPersistentStoreWithCompletion:nil];
  28. [_data removeAllObjects];
  29. }
  30. -(void)refresh {
  31. _page = 1;
  32. _isEnd = false;
  33. _worksRequest.page = _page;
  34. [_worksRequest execute:^(id cacheData){
  35. if(cacheData) {
  36. [_data addObjectsFromArray:cacheData];
  37. }
  38. } requestSuccess:^(id responseObject) {
  39. [_collectionView.header endRefreshing];
  40. WorksListModel *worksListModel = [[WorksListModel alloc]initFromDictionary:responseObject];
  41. if(worksListModel.errNo.intValue == 0) {
  42. _page++;
  43. _isEnd = worksListModel.isEnd.boolValue;
  44. [self clean];
  45. [_data addObjectsFromArray:worksListModel.data];
  46. [_collectionView reloadData];
  47. }
  48. } failure:^(NSError *error) {
  49. [self.view makeToast:@"网络错误"];
  50. [_collectionView.header endRefreshing];
  51. }];
  52. }
  53. -(void)loadMore {
  54. if(!_isEnd) {
  55. _worksRequest.page = _page;
  56. [_worksRequest execute:^(id responseObject) {
  57. [_collectionView.footer endRefreshing];
  58. WorksListModel *worksListModel = [[WorksListModel alloc]initFromDictionary:responseObject];
  59. if(worksListModel.errNo.intValue == 0) {
  60. _page++;
  61. _isEnd = worksListModel.isEnd.boolValue;
  62. [_data addObjectsFromArray:worksListModel.data];
  63. [_collectionView reloadData];
  64. }
  65. } failure:^(NSError *error) {
  66. [self.view makeToast:@"网络错误"];
  67. [_collectionView.footer endRefreshing];
  68. }];
  69. }
  70. }
  71. #pragma datasource & delegate
  72. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  73. return _data.count;
  74. }
  75. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  76. WorksCell *worksCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"WorksCell" forIndexPath:indexPath];
  77. worksCell.worksDB = [_data objectAtIndex:indexPath.row];
  78. return worksCell;
  79. }
  80. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  81. return 1;
  82. }
  83. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  84. CGFloat width = (self.view.frame.size.width - 20) / 3;
  85. return CGSizeMake(width, width * 1.5);
  86. }
  87. - (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
  88. return UIEdgeInsetsMake(5, 5, 5, 5);
  89. }
  90. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  91. return 5.0;
  92. }
  93. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  94. return 5.0;
  95. }
  96. @end

Model考虑的重点:
1)网络,解析通信:AFNetworking(取代ASI)通信,解析可以考虑使用MJExtension
2)数据缓存: CoreData(可以用MagicalRecord框架) 或者直接操作sql(可以选用FMDB框架)。这里CoreData可能效率上没有直接写sql高,但是在一些框架的基础上代码非常简洁,面向对象的思想比较强

如下是对Request的一个操作

[objc] 
view plain
copy

  1. @implementation BaseRequest
  2. - (instancetype)init {
  3. self = [super init];
  4. if (self) {
  5. _params = [NSMutableDictionary new];
  6. _method = RequestMethodGet;
  7. }
  8. return self;
  9. }
  10. -(void)setParam:(NSString *)name value:(NSString *)value {
  11. _params[name] = value;
  12. }
  13. -(void)execute:(void (^)(id responseObject))requestSuccess failure:(void (^)(NSError *error))requestFailure {
  14. AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
  15. if(_acceptableContentTypes) {
  16. manager.responseSerializer.acceptableContentTypes = _acceptableContentTypes;
  17. }
  18. if(_method == RequestMethodGet) {
  19. [manager GET:_url parameters:_params success:^(AFHTTPRequestOperation *operation, id responseObject){
  20. requestSuccess(responseObject);
  21. } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
  22. requestFailure(error);
  23. }];
  24. }
  25. else if(_method == RequestMethodPost){
  26. [manager POST:_url parameters:_params success:^(AFHTTPRequestOperation *operation, id responseObject){
  27. requestSuccess(responseObject);
  28. } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
  29. requestFailure(error);
  30. }];
  31. }
  32. }
  33. -(void)execute:(void (^)(id cacheData))cacheData requestSuccess:(void (^)(id responseObject))requestSuccess failure:(void (^)(NSError *error))requestFailure {
  34. cacheData([self getCacheData]);
  35. [self execute:requestSuccess failure:requestFailure];
  36. }
  37. -(id)getCacheData {
  38. return nil;
  39. }
  40. @end

[objc] 
view plain
copy

  1. @implementation WorksRequest
  2. - (instancetype)init {
  3. self = [super init];
  4. if (self) {
  5. self.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
  6. self.page = 1;
  7. self.method = RequestMethodPost;
  8. }
  9. return self;
  10. }
  11. -(void)setPage:(NSInteger)page {
  12. _page = page;
  13. [self setParam:@"page" value:[NSString stringWithFormat:@"%ld", (long)_page]];
  14. }
  15. -(id)getCacheData {
  16. return [WorksDB MR_findAllSortedBy:@"worksid" ascending:FALSE];
  17. }
  18. @end

View涉及的重点:重点应该体现封装,相同的代码,或者xib尽量抽取,达到重用

布局的方法有xib,storyboard,代码,应该在项目中灵活选用

贯穿项目中的还会用到一些,
block,这里可以考虑一下BlockKit这个框架,对block的一个封装,代码更简洁
SDWebImage图片框架
GCD/OperationQueue多线程

单例:请查看链接:http://blog.csdn.net/sbvfhp/article/details/47861453
KVO:

未完,待续......

-----------------------------------------------------------------------------------------------------------------------

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-27 06:29:47

IOS项目架构分享的相关文章

UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎指点! 基于MVVM的UWP项目架构 每个项目或者目录下需要什么文件如下图所示: 项目参照关系: 备注:如果使用Entity Framework Core做ORM持久层,只需要将UA.DataAccess层做替换就可以.希望本文能对您的团队开发带来一定功效.

iOS项目架构文档

设计的项目架构主要引用MVVM+MVC架构,并以功能模块分级.以下为目录结构. 初级目录: 我们只需要关注SGZH文件夹下的目录,其他为Xcode管理的目录.可以看到此目录为项目初级目录,我们开发过程只需对初级目录内的文件进行操作,其主要划分为3大块: AppDelegate: AppDelegate是程序入口,程序启动和显示逻辑都定义在内部,主要可以让开发人员快速找到代理文件并了解程序从启动到显示过程,也可以快速进行一些初始化测试. Resource: 此目录主要存放一些项目资源文件,如项目切

Asp.net mvc项目架构分享系列之架构搭建初步

copy to:http://www.cnblogs.com/ben121011/p/5014795.html 项目架构各部分解析 Core Models IDAL MSSQLDAL IBLL BLL WebHelper Web AdminLogic 5.项目架构初步搭建 1)      创建一个空白解决方案 2)     添加解决方案文件夹,初步分层UI.Service.Repository.Infrastructure 3)     创建项目(除Web项目外,其他均创建为类库项目) a)  

iOS项目架构

关于项目架构的问题,我想,作为已经具有两年开发经验的本人来说,还是有一些不大不小的问题,下面来总结一下这些问题. 目录结构 AppDelegate Models Macro General Helpers Vendors Sections Resources 一个合理的目录结构首先应该是清晰的,让人一眼看上去就能大概了解目录的职责,且容易应对新的变化. AppDelegate 这个目录下放的是AppDelegate.h(.m)文件,是整个应用的入口文件,所以单独拿出来. Models 这个目录下

iOS 项目架构tabbarController 嵌套 navbarController

简单思路: 进入APP,首先加载 splashVC,加载完成之后,在viewDidAppear里跳转到loginVC,(这里一定要在viewDidLoad方法里新建loginVC跳转). 登陆成功之后,进入tabBarController,tabView里有四个模块,每个模块由navController控制器做导航,可以进入各自的子模块.进入二级子模块要隐藏tabbar. 待补充

iOS项目架构 小谈

层级结构,自底向上 持久层(File,Realm,SQLite)<==>网络层(相信每个公司都有自己的网络层吧)==>业务层(ViewModel)==>展示层(View,VC) 持久层 耦合到网络层 设计要点 持久模型的选择,我这里选择了文件,直接缓存了JSON.txt.并且维护一张表映射到文件,实现快速获取,文件超时删除等操作. 持久层的timeout设置,网络层访问到这里的时候,如果超时立即抛弃缓存 网络层 耦合到持久层 设计要点 网络层的设计是基于离散式的,即一个API接口对

一种比较实用的iOS SDK项目架构

在SDK开发中,一般会需要经过几个流程,开发SDK,测试SDK,把SDK交付给使用人员,这些东西看似步骤多,过程繁琐,而且每修改一次SDK就需要重复一次上述的过程,增加了一些不必要的操作.当然,如果我们在SDK设计之初就有一个好的项目架构,就可以极大简化开发流程,提高开发效率,本文将带读者一步一步设计搭建一个个人认为比较好的SDK开发架构. 创建基本的工作空间 工作空间这个概念对于很多人并不陌生,平时使用得很多的CocoaPods里面其实就使用到了工作空间,具体一些原理在我的另外一篇博客. 打开

李洪强iOS开发之 - 项目架构

李洪强iOS开发之 - 项目架构 01 - 在Appdelegate中设置跟控制器 //导入头文件

Java企业级电商项目架构演进之路 Tomcat集群与Redis分布式百度云实战分享

muke慕课实战课程分享QQ313675301 新增课程: Java企业级电商项目架构演进之路 Tomcat集群与Redis分布式百度云实战分享 后端开发: 1.高级java软件架构师实战培训视频教程2.大型SpringMVC,Mybatis,Redis,Solr,Nginx,SSM分布式电商项目视频教程3.Spark Streaming实时流处理项目实战4.Java校招面试 Google面试官亲授5.Java开发企业级权限管理系统6.Java大牛 带你从0到上线开发企业级电商项目7.Java