iOS 应用开发 (一)

写在前面

应同事邀请, 在简书分享一些开发方面的经验. 所以有了这篇文章.
这不是一篇Objective-C/Swift的学习教程. 我想给那些学完开发语言、了解了一些API阶段的同学们 分享一些开始构建一个App工程时的一些内容.

让我们开始吧.

创建工程

Xcode "Create a new Xcode project"


ios-app-dev-001.jpg

根据你要建立的应用的需求不同, 当然可选不同的模板来初始化工程.

但绝大多数时间, 我推荐你从“Single View App”开始你的项目;

因为其他模板里的功能, 都可以在以后添加进项目, 而一般情况下, 现在的应用有很多必须的东西这些模板里都没有, 例如Splashscreen之后大部分应用都有几页全屏大图的介绍页; 或者很多应用都有的主界面是个tab控制器掌控着多个navigation控制器.

好吧, 坦白说, 其实我们想要的应该是个空的项目有一些基础的配置文件. 大概来说从“Single View App”来开启这个项目更接近我们想要的状态.

ios-app-dev-002.jpg

作为项目的代码肯定是会被VCS(版本控制系统)托管的, 那么创建完初始化工程之后再把它整个丢进仓库吧~ 这里就不用同时创建本地git仓库.

这里我会以单一视图模板来创建一个TestApp工程.

组织工程

组织方式当然就各有不同了.
有的公司有相关规范, 那很好, 遵守它来创建, 你的项目在公司将会更容易被后来人维护;
网络上也有很多人分享他们组织归纳文件的方式, 也可以参考学习;
或者你自己的归纳方法.

这里稍微说一下我常用的:

  • AppDelegate保留在原始位置, 项目根目录;
  • 项目根目录下的归类的文件夹我都习惯以一个下划线开头, 这个习惯要从很久以前的 Finder 排序文件规则并不会优先排列文件夹开始说起, 加了下划线以后, 文件夹出聚集出现在前面;
  • 要展示的每一个界面都归到_Scene目录下;
  • 常量归到_Constant目录下;
  • 模块归到_Module目录下;
  • 图片、音频、字体等资源归到_Resource目录下;
  • XcodeProject Navigator(⌘1) 里的文件夹, 应该和磁盘上的文件夹一一对应; 因为如果Xcode都用虚拟文件夹, 文件一多起来, 它们可能都被凌乱的丢在工程根目录 or 任何地方, 找起来是一大麻烦.

如果照上边一番整理, 我们的初始工程可能会看起来比较像这样:


ios-app-dev-003.jpg

不管你使用哪种方式去组织工程, 遵守它就好.

视窗

这里要说的是关于视图构建的事儿.

Xcode 现在默认都是以 Storyboard 形式创建工程.
Storyboard 有很多优势, 但是我觉得协同工作时, 不是很方便.

大部分时候, 一个项目里会有很多很多的视图/视图控制器, Storyboard会比较大, 打开的速度问题, 在机械硬盘的电脑上尤为明显. (当然希望各公司都给配SSD的Mac)

再就是多人同时编辑一个Storyboard时, 处理VCS里的合并问题; 合并真的太多啦, 毕竟应用开发有很多构建视图的工作.

所以我推荐使用独立的 nib 文件来做视图, 也就是常见的 .xib文件.

这样一来, 它可以像Storyboard一样方便的使用 AutoLayout 超好用的布局设计工具, 又方便团队开发; 而且因为分散界面, 每个文件也很小, 方便读取.

就是少了 Storyboard 里的视图控制器与视图控制器的关联配置, 不过这部分用代码来操作也很方便; 有时候还很必要, 因为我们经常需要在某些代码判断条件下决定视图跳往哪个视图, 有时候我们会在跳转前, 设置一些新视图的属性值等情况.

这样一来, 应用到当前的TestApp工程上:

  • 在工程的 Targets配置里, 删除填写在 Deployment Info > Main Interface里的数据(比如是Main), 让它置空. 因为我们不准备再用这个Storyboard文件了.
  • 从工程里删除对应的Storyboard文件(比如是Main.storyboard)
  • 编辑AppDelegate; 未从Storyboard初始化视窗, 我们需要在代码里手动初始化.

编辑 AppDelegate.m 文件的-application:didFinishLaunchingWithOptions:方法:

// 初始化Window
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

// 配置根视图控制器
_window.rootViewController = 某某试图控制器实例;

// 让window显示出来
[_window makeKeyAndVisible];

依赖管理

基本的工程清理好了, 现在该给它增加依赖管理了.

现在iOS应用常用的依赖管理是 CocoapodsCarthage , 以后还可以用上官方的 Swift Package Manager.

这里呢, 就拿Cocoapods介绍一下.

你当然得安装好Cocoapods; 如果还没, 可以用macOS的一款包管理器Homebrew 来安装它, 命令:

brew install cocoapods

如果连Homebrew也没有, 也可以用一行命令先安装它:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

brew很方便, 现在用来安装Cocoapods, 或是以后想装个Go-lang啊, 或是Vim啊, 又或是carthage、mtr... 那些你想要用的工具, 都可以用它方便的安装与管理.

这里你已经能好好用pod了.

那么命令行进到项目跟目录下:

# 生成Podfile
pod init

# 根据Podfile生成工作空间
pod install

因为还没加任何pod, 所以应该很快会跑完.
正常跑完这个install命令会提示类似如下内容:

[!] Please close any current Xcode sessions and use `TestApp.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There are 0 dependencies from the Podfile and 0 total pods installed.

那从今往后就该使用 *.xcworkspace 文件来打开工程了.

Pod的使用网上有许多参考内容, 这里就不多说. 附上官方网站: Cocoapods.

版本控制

前面说, 项目中的代码肯定是有代码版本控制系统管理在的, 所以我们不在那时又去创建本地git仓库.

现在要将工程代码放到仓库里, 我们就要指定好哪些文件被版本控制系统来管理.

例如这里我们用git系统, 可以在工程根目录放置一个.gitignore文件, 来指明被git系统忽略的文件/文件类型.

推荐一个 git ignore 文件的模板网站: gitignore.io

比如在这选上 Objective-CSwift 语言, 选上 macOS 系统:

ios-app-dev-004.jpg

就可以生成一份它们推荐的这些语言/这些系统下被忽略的文件/文件类型. 可以创建一个空白的.gitignore文件把它们复制粘贴进去.

然后做一点想要的修改.

因为我们在用Cocoapods, 那么稍微思考一下:

  • 这里传入仓库的工程, 其他人克隆出的运行的环境如何? 是内外离线环境吗? 如果不能方便的使用pod install, 那我们则应该将Pods目录也放到仓库(也包括生成的.xcworkspace); 这样克隆后, 依赖库都已经存在, 无需pod install即可直接运行工程;
  • 存在对各个库版本的指定要求吗? 如果是这样, 我们比较应该上传Podfile.lock文件. 这是在操作pod install时, 由pod计算出满足条件依赖设置的情况下, 要下载使用的, 最新版本的各个库 的信息; 也就是说, 这里详细记录着当前你运行的项目里, 使用那些依赖库的版本; 将它加入版本控制, 这样其他人克隆并使用该工程时, pod install会直接读取这个.lock文件指定的版本信息, 保持使用库的版本一致. 这种情况, 可以将Pods以下所有文件忽略.
  • 还有其他情况? 要不要忽略Podfile.lock文件呢? 这是没有特定答案的. 你需要考虑的是, 忽略/添加的后果是什么. 前面说了添加它可以用来确保协作时使用同一版本; 那忽略它, 意味着每一次(无Podfile.lock)文件下的pod install, 都会挑选满足条件下的最新版本库. 这样的话, 如果某些库的API变更导致你的使用也需要调整时, 你得及时修复. 另外, 如果你用CI, 遇到这种情况CI是不会帮你修复的. (同理, CI上一定是要跑pod install而不是pod update).

这里我们选择记录 Podfile, Podfile.lock, 忽略 Pods.

贴出来瞧瞧:

# Created by https://www.gitignore.io/api/macos,swift,objective-c

### macOS ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Objective-C ###
# 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
*.dSYM.zip
*.dSYM

# CocoaPods - Refactored to standalone file
Pods/*

# Carthage - Refactored to standalone file

# 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://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/

### Objective-C Patch ###

### Swift ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated

## Various settings

## Other

## Obj-C/Swift specific

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
.build/

# CocoaPods - Refactored to standalone file

# Carthage - Refactored to standalone file

# 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://docs.fastlane.tools/best-practices/source-control/#source-control

# End of https://www.gitignore.io/api/macos,swift,objective-c

小结

到这里, 初始化工程的任务就完成啦!~

我们回顾一下:

  • 创建了工程;
  • 定义/组织好工程目录结构;
  • 挑选了工程视图构建方式;
  • 配置了依赖管理系统;
  • 配置了版本控制系统.

作者

骆昱(Luo Yu), 2018-05-09

邮箱: luoyu@luoyu.space

知识共享许可协议

本作品采用知识共享署名 3.0 中国大陆许可协议进行许可。



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352