之前为公司定了一个内部的 iOS 工程规范,其实也是我个人的风格,下面记录一下发出来。
warning
: 类似数据类型隐式转换这种低级的 warning
绝不能出现。类似 perform unrecognizer selector
这种 warning
可以用 #pragma clang diagnostic push
这种编译指令将其去掉(所有 warning
参见 fuckingclangwarnings.com)。对于 CocoaPods
安装第三方库带来的 warning
可以在 Podfile
中配置 inhibit_all_warnings!
去掉。对于开发者自己打的 warning
,在发布版本之前要逐个检查,确认无误或者完成后才能发布。README.md
和 CHANGELOG.md
,建议每个代码文件夹写一个 README.md
说明该模块是做什么的,起到文档作用。两种建议(假设下面的工程以 DMP 为前缀):
第一种是先按代码逻辑划分,再在每个目录中按功能模块细分:
|—— DemoProject
| |—— Common: 存放全局通用的头文件,例如 DMPConstants.h, DMPAppKeys.h, DMPMacros.h
| |—— Vendor: 不适合通过 CocoaPods 引入的第三方类库,例如需要经常改动的或者自己定制的
| |—— Resources: 存放各种资源,例如语言国际化文件组成的 bundle 文件,Images.xcassets 等
| |—— Utils: 工具类,可以便捷地迁移到其它工程
| | |—— Categories: 存放各种 Category
| | |—— Helpers: 例如获取设备信息、App 信息之类的工具类
| |—— Models: 数据模型类
| |—— Logic: 各种业务逻辑类
| | |—— Global: 例如 App Config,Notification Center 这种全局通用的
| | |—— SDKWrapper: 为了避免 AppDelegate.m 过于庞大,可以把一些 SDK 逻辑封装下单独出一个类
| | |—— Network: 网络逻辑
| | |—— Storage: 数据持久化
| | |—— Cache: 缓存
| | |—— 其它根据工程自行拓展
| |—— Views: 视图类
| | |—— Common: 所有全局共用的 UI 组件
| | |—— TableView:
| | | |—— Headers: UITableView 的 Headers
| | | |—— Cells: UITableViewCell 子类
| | | |—— Footers: UITableView 的 Footers
| | |—— CollectionView:
| | | |—— ReusableViews: UICollectionReusableView 子类
| | | |—— Cells: UICollectionViewCell 子类
| | |—— Storyboards: 存放一个或多个 storyboard 文件
| | |—— Others: 针对特定场景定制的 UI 组件,根据功能划分模块,例如 Login, Home, My
| |—— Controllers: 视图控制器类
| | |—— Base: 各种 ViewController 的根类,例如 DMPBaseViewController, DMPBaseTableViewController
| | |—— Entrance: 存放各种 App 启动时的入口页面控制器,例如配置入口的 DMPControllersManager, 闪屏 DMPSplashController, 引导页 DMPIntroduceController, 正常入口 DMPRootTabBarController 等
| | |—— 根据功能划分模块,例如 Login, Home, My
| |—— AppDelegate.h/m
| |—— Supporting Files
| | |—— Info.plist, main.m, pch 等
|—— DemoProjectUnitTests: 单元测试对应的目录
|—— Scripts: 在 Archive 时自动保存 dSYM 文件的脚本,读取 dSYM 和 Crash 的脚本等,不用添加到 Xcode 工程中
| |—— dSYM: 存放每次 Archive 生成的 dSYM
第二种是先按功能模块划分,再按代码逻辑划分:
假设有 Entrance, Home, Games, My 几个功能模块,分别表示程序入口,主页,游戏页面,个人主页。
|—— DemoProject
| |—— Vendor: 不适合通过 CocoaPods 引入的第三方类库,例如需要经常改动的或者自己定制的
| |—— Resources: 存放各种资源,例如语言国际化文件组成的 bundle 文件,Images.xcassets 等
| |—— Base: 基础模块,为具体功能模块做支撑
| | |—— Common: 存放全局通用的头文件,例如 DMPConstants.h, DMPAppKeys.h, DMPMacros.h
| | |—— Models: 数据模型类
| | |—— Views: 全局通用的视图类,自定的 UI 组件祖先类放在这里
| | |—— Controllers: 各种 ViewController 的根类,例如 DMPBaseViewController, DMPBaseTableViewController
| | |—— Helpers: 便于迁移到其它工程的工具类
| | |—— Categories: 各种 Category
| | |—— Logic: 负责各种基础逻辑的类
| | | |—— Global: 例如 App Config,Notification Center 这种全局通用的
| | | |—— SDKWrapper: 为了避免 AppDelegate.m 过于庞大,可以把一些 SDK 逻辑封装下单独出一个类
| | | |—— Network: 网络逻辑
| | | |—— Storage: 数据持久化
| | | |—— Cache: 缓存
| | | |—— 其它根据工程自行拓展
| |—— Modules: 各种功能模块
| | |—— Entrance: App 入口模块
| | | |—— Interfaces: 本模块公用的头文件,例如一些公用的常数、宏、Protocol、enum 定义等
| | | |—— Models: 本模块用到的数据模型类
| | | |—— Views: 本模块涉及的页面类
| | | |—— Controllers: 本模块涉及的视图控制器类
| | | |—— Helpers: 本模块涉及的业务逻辑类,例如负责布局的 LayoutUtil,负责动画的 AnimationUtil
| | |—— Home: 主页模块
| | | |—— ...
| | |—— Games: 游戏模块
| | | |—— ...
| | |—— My: 个人主页模块
| | | |—— ...
| |—— AppDelegate.h/m
| |—— Supporting Files
| | |—— Info.plist, main.m, pch 等
|—— DemoProjectUnitTests: 单元测试对应的目录
|—— Scripts: 在 Archive 时自动保存 dSYM 文件的脚本,读取 dSYM 和 Crash 的脚本等,不用添加到 Xcode 工程中
| |—— dSYM: 存放每次 Archive 生成的 dSYM
两种各有优缺点,可以自行根据喜好选择合适的结构。
在 Build Settings 中设置 Enable Modules 和 Link Frameworks Automatically 为 YES,避免手动引入各种系统 frameworks.
App 尽量使用 Images.xcassets 进行管理,必须包含 @2x 和 @3x 文件,较大的图片或背景图片可以使用 JPEG 格式代替。
图片文件命名采用 prefix_module_identifier_state
规则。
prefix
表示图片类型的前缀,举例:
module
表示所属的场景模块,例如:common, home, my 等。
identifier
表示图片的标识。
state
表示素材的状态,例如按钮处于正常状态还是选中状态。
举例:icon_common_setting, btn_home_play_selected.
App 统一使用 CocoaPods 进行第三方依赖管理, SDK 尽量避免引入第三方类库。
Podfile 示例:
platform :ios, '7.0' # 指定 App 最低版本
# Target for App
target "H5GameCenter" do
pod 'AFNetworking', '~> 2.6.0' # 需要指定版本号
inhibit_all_warnings! # 禁止所有 warnings
end
# Target for Unit Tests
target "HGCUnitTests" do
pod 'OHHTTPStubs', '~> 4.3.0'
inhibit_all_warnings!
end
小提示:如果每次都用 pod install
命令安装,会非常慢,因为 CocoaPods 会检测类库是否需要更新,可以使用 pod install --no-repo-update
绕过检测更新进行安装。
1.分支管理统一用 git flow
2.Objective-C 工程 .gitignore 规范
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
fastlane/report.xml
fastlane/screenshots
3.commit message 不能太随意
对关键的逻辑必须要有单元测试。
暂无。