Py学习  »  Git

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

程序员大咖 • 6 年前 • 494 次点击  

来自: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’ dopod '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谢谢……



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/l6GQHIJ2Ph
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/4060
 
494 次点击