码迷,mamicode.com
首页 > 移动开发 > 详细

IOS项目架构分享

时间:2015-09-15 15:07:31      阅读:333      评论:0      收藏:0      [点我收藏+]

标签:

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




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


如下是对Request的一个操作

[objc]  view plain copy
  1. @implementation BaseRequest  
  2.   
  3. - (instancetype)init {  
  4.     self = [super init];  
  5.     if (self) {  
  6.         _params = [NSMutableDictionary new];  
  7.         _method = RequestMethodGet;  
  8.     }  
  9.     return self;  
  10. }  
  11.   
  12. -(void)setParam:(NSString *)name value:(NSString *)value {  
  13.     _params[name] = value;  
  14. }  
  15.   
  16. -(void)execute:(void (^)(id responseObject))requestSuccess failure:(void (^)(NSError *error))requestFailure {  
  17.     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];  
  18.     if(_acceptableContentTypes) {  
  19.         manager.responseSerializer.acceptableContentTypes = _acceptableContentTypes;  
  20.     }  
  21.       
  22.     if(_method == RequestMethodGet) {  
  23.         [manager GET:_url parameters:_params success:^(AFHTTPRequestOperation *operation, id responseObject){  
  24.             requestSuccess(responseObject);  
  25.         } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  26.             requestFailure(error);  
  27.         }];  
  28.     }  
  29.       
  30.     else if(_method == RequestMethodPost){  
  31.         [manager POST:_url parameters:_params success:^(AFHTTPRequestOperation *operation, id responseObject){  
  32.             requestSuccess(responseObject);  
  33.         } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  34.             requestFailure(error);  
  35.         }];  
  36.     }  
  37. }  
  38.   
  39. -(void)execute:(void (^)(id cacheData))cacheData requestSuccess:(void (^)(id responseObject))requestSuccess failure:(void (^)(NSError *error))requestFailure {  
  40.     cacheData([self getCacheData]);  
  41.     [self execute:requestSuccess failure:requestFailure];  
  42. }  
  43.   
  44. -(id)getCacheData {  
  45.     return nil;  
  46. }  
  47. @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.   
  12. -(void)setPage:(NSInteger)page {  
  13.     _page = page;  
  14.     [self setParam:@"page" value:[NSString stringWithFormat:@"%ld", (long)_page]];  
  15. }  
  16.   
  17. -(id)getCacheData {  
  18.     return [WorksDB MR_findAllSortedBy:@"worksid" ascending:FALSE];  
  19. }  
  20. @end  


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

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




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

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



未完,待续......

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

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

IOS项目架构分享

标签:

原文地址:http://my.oschina.net/hejunbinlan/blog/506269

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!