专栏名称: 程序员大咖
为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等。并不定期奉送各种福利。
目录
相关文章推荐
程序猿  ·  2023 年最受欢迎 Linux 发行版本公布 ·  5 天前  
程序员小灰  ·  所有快倒闭公司的通病。 ·  4 天前  
程序员的那些事  ·  趣图:在我机器上好好的(Ծ‸Ծ) ·  1 周前  
程序猿  ·  红帽RHEL将成为微软官方WSL发行版 ·  1 周前  
程序猿  ·  多年的编程教会了我 ·  1 周前  
51好读  ›  专栏  ›  程序员大咖

iOS APP框架搭建简析(附GitHub托管Demo)

程序员大咖  · 公众号  · 程序员  · 2017-04-17 19:05

正文

来自:http://www.jianshu.com/p/89e25c288d76


都说“三岁看老”,我在和谐社会中摸爬 打滚了也近三个年头,这不快过年了,今年朋友/发小寻找“心理平衡”的首选对象依旧是哥,看着大家满意而归的身影,荣幸之至!捧一捧凉水扑到脸上,抬头照照镜子打量着依旧“枯瘦如柴”的自己,看着时间给刻下的“抬头纹”,盯着那浑浊但依旧坚定的眼睛,哥想对自己说:“大雁,你可以的,虽然没有以前好配合了,你终有一天会成功的,虽然还很遥远!乖乖,好了,傻B可以写帖子了……”

前言

不管开发任何软件,我们的原则就是尽量做到“高内聚低耦合”。所谓“低耦合”是指软件结构中模块与模块之间的耦合度或关联程度,模块之间接口的调用及实现的复杂度、交互数据的多少等,决定了软件耦合度的高低强弱;所谓“高内聚”是从模块内部功能的层面而言的,模块内部特定功能的代码元素的紧密程度决定了代码内聚性的高低。

网上不乏有所谓“十分钟搭建强壮APP框架”、“快速搭建强壮APP框架”等帖子,且不去讲好坏,总之,实践是检验真理的唯一标准,今天我简单汇报下本人做项目时,框架的搭建流程及注意事项。

框架搭建

框架搭建是个劳神费心的事情,因为在搭建时你要考虑到各种可能,比如:怎么设计使得流程更清晰?怎么设计更易于分工协作?怎么设计更容易快速定位代码模块?怎么保证系统的易扩展性?等等都是我们要提前把握好的。先看下大致效果图如下:


一、 框架结构

APP的结构一般分为三条线:

  • 一条主框架流程;

  • 一条是用户登录框架流程;

  • 一条其他如广告页、欢迎页等

相对而言,主框架流程较为复杂,顶级容器为UITabBarController,子容器为UINavigationController,其中顶级容器放3-5个导航控制器,导航控制器的rootViewController为各模块的首页。登录框架流程及其他一般为线性流程,个别会涉及到根视图的切换,相对简单,如果画成树状结构图的话大致如下:

二、 StoryBoard分离

为了配置三方库方便,我使用CocoaPods工程(基于CocoaPods 1.1.1),下为Podfile文件引入的三方库:

platform :ios,’8.0’

target ‘EVNEstorePlatform’ do

pod 'MBProgressHUD', '~> 1.0.0'
pod 'FMDB'
pod 'SDWebImage', '~> 3.8'
pod 'IQKeyboardManager', '~> 3.3.7'
pod 'MJRefresh'
pod 'MJExtension'
pod 'MWPhotoBrowser'
pod 'AFNetworking', '~> 3.0'

end

如遇到问题,可参照CocoaPods工作原理及使用中遇到的问题,解决或问阿度。

在实际的项目开发中,没有说谁的框架更优,结构都是大同小异,适合自己的团队才是最重要的。单从框架搭建及界面布局而言,有的团队喜欢StoryBoard,因为所见即所得,给外行介绍起来较为方便,一个模块的所有的界面铺满屏幕,很酷炫的感觉。有的团队喜欢纯代码,当看到自己写一串串字符渲染出“神秘”动画,说不出的满足感。当然我们团队奉行的是中庸之道,框架搭建+个别简易界面我们使用StoryBoard,其他使用纯代码的方式,这也是踩过坑之后,倒逼的结果。

毋庸置疑StoryBoard有很多的优点,但对于团队协作开发,有时会有说不出的痛,比如:同时修改StoryBoard文件遇到的冲突;即便是细微的位移调整,编译起来也需要足够耐心;更新了下Xcode怎么布局全乱了等等问题,正因为此,我们采用折中方案,尽量将StoryBoard分离使用,Main.storyboard中为主框架顶级容器和登录流程的顶级容器,而其他3-5个模块如,首页Host.storyboard、个人中心MineCenter.storyboard等,使用单独的StoryBoard文件,除此之外基本使用纯代码方式编写。

在进行故事版分离时,主要是自定义UITabBarController的过程。
首先,根据上面模板图,新建故事版文件;
然后,按照第一节框架结构图,将特定的控制器容器、导航控制器、视图控制器拖入对应的故事版中(StoryBoard文件);
再次,在自定义的UITabBarController中,连接各个模块,在这个过程中UITabBarController起到了应用的连接中枢的作用,为了炫技,哥做了个中间凸起效果,主要的TabBarController代码如下:

#pragma mark: 首页storyboard
    UIImage *hostSelectImg = [UIImage imageNamed:@"hostViewSelect"];
    UIImage *hostUnSelectImg = [UIImage imageNamed:@"hostViewUnSelect"];
    UIStoryboard *hostSB = [UIStoryboard storyboardWithName:@"Host" bundle:nil];
    UINavigationController *hostNaviVC = [hostSB instantiateViewControllerWithIdentifier:@"hostNavigationC"];
    hostNaviVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"首页" image:[self scaleImage:hostUnSelectImg] selectedImage:[self scaleImage:hostSelectImg]];
    hostNaviVC.tabBarItem.tag = 0;

#pragma mark: 关注storyboard
    UIImage *attentionSelectImg = [UIImage imageNamed:@"attentionSelect.png"];
    UIImage *attentionUnSelectImg = [UIImage imageNamed:@"attentionUnSelect.png"];
    UIStoryboard *attentionSB = [UIStoryboard storyboardWithName:@"Attention" bundle:nil];
    UINavigationController *attentionNaviVC = [attentionSB instantiateViewControllerWithIdentifier:@"attentionNavigationC"];
    attentionNaviVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"关注" image:[self scaleImage:attentionUnSelectImg] selectedImage:[self scaleImage:attentionSelectImg]];
    attentionNaviVC.tabBarItem.tag = 1;

#pragma mark: 发现storyboard
    UIImage *findSelectImg = [UIImage imageNamed:@"findSelect.png"];
    UIImage *findUnSelectImImg = [UIImage imageNamed:@"findUnSelect.png"];
    UIStoryboard *findSB = [UIStoryboard storyboardWithName:@"Find" bundle:nil];
    UINavigationController *findNaviVC = [findSB instantiateViewControllerWithIdentifier:@"findNavigationC"];
    findNaviVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"发现" image:[UIImage imageWithCGImage:findUnSelectImImg.CGImage scale:1.5 orientation:findUnSelectImImg.imageOrientation] selectedImage:[UIImage imageWithCGImage:findSelectImg.CGImage scale:1.5 orientation:findSelectImg.imageOrientation]];
    [findNaviVC.tabBarItem setImageInsets:UIEdgeInsetsMake(-14, 0, 14, 0)];
    findNaviVC.tabBarItem.tag = 2;
    findNaviVC.tabBarItem.selectedImage = [[UIImage imageNamed:@"findSelect.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    findNaviVC.tabBarItem.image = [[UIImage imageNamed:@"findUnSelect.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

#pragma mark: 购物车storyboard
    UIImage *goodsCarSelectImg = [UIImage imageNamed:@"goodsCarSelect.png"];
    UIImage *goodsCarUnSelectImg = [UIImage imageNamed:@"goodsCarUnSelect.png"];
    UIStoryboard *goodsCarSB = [UIStoryboard storyboardWithName:@"GoodsCar" bundle:nil];
    UINavigationController *goodsCarNaviVC = [goodsCarSB instantiateViewControllerWithIdentifier:@"goodsCarNavigationC"];
    goodsCarNaviVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"购物车" image:[self scaleImage:goodsCarUnSelectImg] selectedImage:[self scaleImage:goodsCarSelectImg]];
    goodsCarNaviVC.tabBarItem.tag = 3;

#pragma mark: 个人中心storyboard
    UIImage *mineCenterSelectImg = [UIImage imageNamed:@"mineCenterSelect.png"];
    UIImage *mineCenterUnSelectImg = [UIImage imageNamed:@"mineCenterUnSelect.png"];
    UIStoryboard *mineCenterSB = [UIStoryboard storyboardWithName:@"MineCenter" bundle:nil];
    UINavigationController *mineCenterNaviVC = [mineCenterSB instantiateViewControllerWithIdentifier:@"mineCenterNavigationC"];
    mineCenterNaviVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"我" image:[self scaleImage:mineCenterUnSelectImg] selectedImage:[self scaleImage:mineCenterSelectImg]];
    mineCenterNaviVC.tabBarItem.tag = 4;

#pragma mark: 连接
    self.viewControllers = @[hostNaviVC, attentionNaviVC, findNaviVC, goodsCarNaviVC, mineCenterNaviVC];

最后, 创建各模块对应的视图控制器,将其匹配到StoryBoard中的控件中。

三、 APP使用流程

APP运行的流程一般为,首先执行AppDelegate的代理方法didFinishLaunching,进入启动页,判断是否是首次使用APP,如果是进入欢迎页,否则直接验证广告页验证,进而进入加载广告页,最后进入首页。具体流程图如下:

我的框架也是根据这个流程搭建。

结语

战战兢兢,如履薄冰,望再接再厉,下为工程托管地址,EVNEstorePlatform GitHub:https://github.com/zonghongyan/EVNEstorePlatform.git,如果觉得有帮助,请不要吝啬点赞,可以在GitHub给个star,O(∩_∩)O谢谢……


本文内容的相关公众号推荐

程序员共读

Java编程精选↓



更多推荐年薪百万的程序员都在干什么?

涵盖:程序人生、算法与数据结构、黑客技术与网络安全、大数据技术、前端开发、Java、Python、Web开发、安卓开发、iOS开发、C/C++、.NET、Linux、数据库、运维等