惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Security Affairs
N
News and Events Feed by Topic
T
Tenable Blog
P
Proofpoint News Feed
W
WeLiveSecurity
Simon Willison's Weblog
Simon Willison's Weblog
Google DeepMind News
Google DeepMind News
C
CERT Recently Published Vulnerability Notes
Help Net Security
Help Net Security
I
Intezer
T
Threat Research - Cisco Blogs
S
Secure Thoughts
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
Google Online Security Blog
Google Online Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
The Hacker News
The Hacker News
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tor Project blog
N
News | PayPal Newsroom
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
A
Arctic Wolf
Forbes - Security
Forbes - Security
O
OpenAI News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Security Latest
Security Latest
P
Palo Alto Networks Blog
S
Schneier on Security
S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
H
Heimdal Security Blog
V
Vulnerabilities – Threatpost
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园_首页
T
Troy Hunt's Blog
Latest news
Latest news
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
L
LINUX DO - 热门话题
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium
V
Visual Studio Blog
H
Hacker News: Front Page

土土哥的Blog

好久没有更新博客=。= 阿里巴巴国际无线技术部 - 招人啦~求iOS、Android、Java 转-阿里巴巴国际无线技术部 - 在这里遇见最好的自己 反编译分析并模拟实现methodSignatureForSelector方法 反编译分析Xcode8的Bug, release下连续两次调用有二级指针参数的空方法会Crash 有趣的Autolayout示例5-Masonry实现 在对象dealloc的后期执行Task-开源库TTGDeallocTaskHelper 用QuartzCode快速实现一个收藏动画 开源项目-拼图验证控件TTGPuzzleVerify的实现 Swift开源Mac App - BingWallPaper 有趣的Autolayout示例4-Masonry实现 翻译-为什么objc_msgSend必须用汇编实现 API返回结果设计经验与总结 结合访问Out Parameters出现EXC_BAD_ACCESS的例子,反编译汇编解读__autoreleasing 总结一些iOS项目中组织代码的方法 对组件化与模块化的思考与总结 开源项目-TTGTagCollectionView 有趣的Autolayout示例3-Masonry实现 Swift开源项目: TTGEmojiRate的实现 Swift写的库-TTGSnackbar 有趣的Autolayout示例2-Masonry实现 解决iOS项目的版本兼容问题-结合宏、Category和Runtime 用Runtime的手段填充任意NSObject对象的nil属性 有趣的Autolayout示例-Masonry实现 UITextView编辑时插入自定义表情-续-自定义表情图片的大小 RPC框架Thrift例子-PHP调用C++后端程序 GCD使用经验与技巧浅谈 为GCD队列绑定NSObject类型上下文数据-利用__bridge_retained(transfer)转移内存管理权 Enum-枚举的正确使用-Effective-Objective-C-读书笔记-Item-5 @autoreleasepool-内存的分配与释放 有关宏定义的经验与技巧-简化代码-增强Log Effective-Objective-C-读书笔记-Item-4-如何正确定义常量 UITextView编辑时插入自定义表情-简单的图文混编 关于评论不见了=。= Entity和Model的不同-关于代码的数据层 一次审核被拒的经历-关于iCloud到底应该备份什么数据 Block类型变量-缓存Http请求与回调 提升UITableView性能-复杂页面的优化 NSString的Copy与内存分配 利用NSProxy实现消息转发-模块化的网络接口层设计-原创 Effective-Objective-C-读书笔记-Item-3 Effective-Objective-C-读书笔记-Item-2 Effective-Objective-C-读书笔记-Item-1 Android开源库-LinkTextView-原创 第一篇Blog
iOS项目的目录结构-原创
土土哥 · 2015-02-01 · via 土土哥的Blog

前言

这段时间一直在做iOS的项目(青桔音乐App),随着代码量的上升,逐渐意识到项目的整体目录结构划分是多么重要,清晰的目录结构,能够更好的应对新的需求,更容易重构。虽然一直都是一个人在做=。=,但是还是深深地体会到目录结构的重要性。

例子

说再多都不如来个例子实在,如下:(VC指的是viewController)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|---General
|---AppDelegate
|---Application
|---Constant
|---UI
|---View
|---VC
...
|---Category
...
|---Entity
|---BaseEntity
|---UserEntity
|---CommentEntity
...
|---Http
|---Api
|---Manager
|---CodeHandler
|---ErrorHandler
|---HttpHandler
|---UserHttpHandler
|---CommentHttpHandler
...
|---DB
|---DBHelper
|---DBService
...
|---Util
|---StringUtil
|---NumberUtil
|---TimeUtil
...
|---Service
|---AccountService
|---ShareService
...
|---Lib
|---Umeng
|---QQSDK
|---SVProgressHUD
...
|---Module
|---Login
|---View
|---VC
|---XIB
|---Comment
|---View
|---VC
|---XIB
|---Business
|---Feeds
...

乍一看好多,别被吓到=。=,容我细细讲解。

详细讲解

General

General好理解,放的就是如AppDelegate之类的、项目中最普通的、最常用的组件。

AppDelegate:

App的Delegate类实现,这个必须有,就不用说了吧。

Application:

如果自定义实现了Application类,就放在这里。

Constant:

顾名思义,常量,项目用到的所有公共常量,如enum枚举类型的、Notification的Tag,常用的颜色、字符串等等等,都可以按照自己的需求划分不同的Group,放到Constant里面。

UI:

项目中自定义的UIView、UIViewController子类之类的代码,就对应放在UI下的View、VC中。

Category:

对系统类做的扩展,各种Category,如NSString+XXXExtension这种,就统一放在Category目录下。

如还有其他的通用组件,也不妨放到这里,做统一的管理。


Entity

Entity,也有人喜欢叫Model(关于Entity和Model的区别,推荐看看这篇文章,个人觉得研究研究Entity和Model概念的区别还是很有好处的),就是程序中的“实体”,如一个用户、一条评论、一首歌等等,简单来说就是一个独立“个体”的集合、打包,具体的自己查查吧,网上一大堆的,感觉跟JavaBean的概念比较像。

通常来说,每个Entity类都比较简单,只包含若干个属性。但是有时候可能要做统一的处理,如,在从服务器取回的JSON数据解包成具体的Entity类,并且执行一系列初始化操作等等,所以可能要对所有的Entity类做统一处理。所以说,可以定制相应的BaseEntity基类,利用模板方法等办法,定制统一的初始化流程(好像扯远了=。=,这个后面会详细写篇东西分享给大家),BaseEntity就是放这些基类的东西的。

有了BaseEntity后,对应的各个业务中的具体Entity,如UserEntity、CommentEntity,就可以分门别类的建立单独的Group存放。


Http

这个Group里面放跟网络请求相关的东西,详细如下:

Api:

互联网应用少不了跟服务器打交道的各种网络接口,所以我在项目中把所有的API对应的相对URL地址、参数注释要求等等都放在了这里,好统一管理。

Manager:

定义最基本的网络请求,如GET、POST、PUT等请求的基本封装,获取图片的基本封装。
一般来说就是定制统一的基本请求接口,对上层提供一致、稳定的服务,真正的网络请求,可以自己用iOS原生的Api写,也可以用AFNetworking等第三方库做封装,图片也可以灵活的用AFNetworking、SDWebImage这些优秀的库实现。还有就是,可以方便的统一对请求做处理,如错误处理、Http的Code、状态处理等等。还可以统一的增加请求参数,如统一为每个请求都增加用户的ID、token什么的。

CodeHandler

大部分的API设计都会有相应的状态码、Code,为了方便扩展,可以把这些处理Code的类单独放在这里。

ErrorHandler

这个就少不了了,对Http的错误进行单独处理,加Log什么的。

HttpHandler

这个Group里面放的是真正实现接口的类,如什么UserHttpHandler、CommentHttpHandler之类的,就是具体实现了接口调用、处理返回数据、回调的类。

Http里面的各个Group的类其实都是相互关联的,设计的时候可以定制统一的接口(Protocol),然后创建类实现(conform)这些接口,也就是面向接口的编程,以最大限度的减少接口层的各个职能之间的耦合,方便扩展。


DB

介于iOS的SQLite不是那么好用,所以非常有必要为操作数据库的类建立单独的地盘=。=

DBHelper:

放基础的操作数据库的类,如简单的查找、插入、更新、事务更新等等操作,为负载的数据库业务逻辑封装底层接口。比如对流行的FMDB进行封装等等。

DBService:

这里放具体的数据库业务实现类,至于为什么叫“Service”,因为我也想不出什么好的名字了=。= 按照自己的业务逻辑组织即可。


Util

放常用的工具类的地方。如字符串操作的类StringUtil、时间计算格式化类TimeUtil等,按具体需求而定,这个就不用多说了吧。


Service

项目的需求多了,业务逻辑的代码就会越来越多,总不能都放在view controller里面吧。一些多处用到的,或者非常独立的业务代码,完全可以抽离出来,实现为单独的、跟界面无关的业务类。因为做的事很杂,所以干脆就叫Service了。

AccountServiceShareService就是这种类。而且大部分的Service都应该是单例类,如AccountService类可能维护着程序运行期间的账户信息,ShareService对程序的分享功能做了统一处理等等,具体怎么用就随各位了。


Lib

Lib,放各种第三方库,因项目需要修改过的第三方组件等,像什么友盟、QQSDK之类的就可以放这。当然,一些不会做改动的库最好还是用CocoaoPod做统一管理。


Module

终于讲到了最重要的地方。

iOS工程中最多的文件往往就是各种View、ViewController类,以前总是看到有人只创建两个Group,一个叫Views,另一个叫ViewControllers,然后所有的Views、ViewController都往里面塞,然后随着需求的增加,这两个Group也臃肿不堪。。。

办法总是有的。就是为工程划分模块-Module

如何划分Module?我认为,可以按照以下两点建立:

  1. 以页面跳转分支划分。
  2. 以功能划分。

以页面跳转分支划分

就是按照应用的页面设计与业务逻辑,从最顶级开始,一级一级页面往下跳转,找出其中的独立分支,归为一个Module模块。
举例来说,应用主界面有4个Tab页,就先分出四个Module,然后一级一级往下跳转,遇到分支就建立新的Module,如此递归的建立,就能大致划分出各个Module。当然,这么做是最粗糙的,还要根据情况,将不同的分支Module合并成一个Module,简化代码的组成。我在这只是提供个划分Module的方法,具体怎么设计就看各位读者了=。=

以功能划分

这个好理解,无非就是根据前期项目的功能模块划分工程的代码Module组成。如什么用户设置Module、评论Module、登录Module等等。

总的来数,就是要用Module将工程的代码分类管理,每个Module具有大致相同的结构,如都可能有本Module用到的View、ViewController,自定义的类Class等等,就是说,按照职能对代码划分,避免将所有的类都堆在一起,也好应对新的需求。

总结

啰啰嗦嗦说了一大堆,想必各位都看烦了吧=。=刚开始写博客,写到一个地方,又会引出另一块,写着写着容易写偏了。

写之前我也大致搜了一下,发现网上相关的资料好少,但是实际的经验告诉我,项目工程的目录结构非常重要,无论是对开发还是对后期的维护,所以想着应该写篇东西,分享我自己的经验给大家,有啥问题,多提意见啊~~~