详解iOS Project和Targets配置
最近开始学习完整iOS项目的开发流程和思路,在实际的项目开发过程中,我们通常需要对项目代码和资料进行版本控制和管理,一般比较常用的SVN或者Github进行代码版本控制和项目管理。我们iOS项目的开发工具Xcode本来就集成了Github的代码控制,所以用GitHub会更方便一些,想具体了解Xcode和GitHub链接具体操作步骤的小伙伴可以戳这里:iOS学习——Xcode9上传项目到GitHub。
创建完项目之后,我们再对一个项目进行代码开发之前,我们首先需要对iOS项目的开发环境进行搭建,我们的应用名称、项目名称、应用图标、启动图片等都是在这一步进行设置的,所以这一部分是整个项目开发的基础,在后续的开发过程中也经常会有些设置需要用到这里的步骤进行修改。但是目前网上查到的资料都非常简短和零散,所以今天我们希望对Xcode上iOS项目搭建各种细节都进行一个详尽的了解和学习。
一 Project 和 Targets区别
首先,iOS项目的开发环境搭建主要就是基于我们项目的Project 和 Targets进行展开的。那么,这两个东西到底是啥玩意呢?我们点击我们的项目名,就会出现下图所示的界面。从图片中可以看到,在项目导航面板的右侧面板上有蓝色和红色框所示的PROJECT和TARGETS两部分。
PROJECT和TARGETS到底是什么意思呢?简单解释如下:
project:project是所有文件、资源、信息/配置的repository。一个project包含所有build your products所需的内容并且维护他们之间关系。它可以包含多个targets。一个project为所有的target定义默认的build setting(每一个target可以自定义它们的build setting,这些自定义的setting会覆盖project默认的build setting,这个在后面会讲到)。 target:简单地说,target定义了project的编译设置,确定了project中各种资源和代码的编译顺序。每个target都唯一依赖于一个project,但是一个project中可以有多个targets,上图所示的target就有2个(KLBaiSi、KLBaiSiTest),每一个的设置不同,但是同一时间里只有一个active Target,在编译时我们可以选择用哪一个target进行编译,具体操作选择如下图所示。一个Target和它的product可以和其他Target联系,如果一个target build需要另一个target的“输出”,可以说成第一个target依赖第二个。如果这俩个target在同一个workspace,Xcode会发现他们的依赖关系,从而build the products按照特定的顺序。这样的关系被称为“ implicit dependency.” 你也可以为俩个targets指定明确的target 依赖关系在build setting里面。例如,你可能build一个library和一个链接这个library的application(同一个workspace)。Xcode可以发现这种关系并且自动build这个library first。然而,你如果要去链接library的某个版本而不是one built in the workspace,你可以在build settings里创建一个确定的依赖关系,它将会覆盖implicit dependency。
二 project和target的属性设置
关于project和target的属性设置,如下图所示就是project和target的属性设置界面,左边是project的属性设置界面,右边是target的属性设置界面。相对而言project的比较简单,只有info和build setting两项,毕竟只是对项目资源进行简单的设置,而target的设置则比较复杂,有general、capabilities、resource tags、 info、build setting、build phases和build rules七项,因为target的每一项设置都直接决定了我们最终App的显示效果。下面我们就一一来学习和了解各个界面的设置有什么作用。
2.1 project属性设置
project的属性设置有两块内容,info和build setting,但是project的build setting和target的build setting之间是相关的,target的build setting的一部分设置会继承project的build setting部分。所以,project的build setting部分内容就放在2.2target属性设置部分进行统一讲解,本小节就主要了解project的info属性设置部分,info属性的界面如下:
主要分为三部分:Deployment Target、Configurations和Localizations。
Deployment Target:部署配置,主要是对本project的生成的App的可以运行的最低版本进行配置,默认是当前Xcode上API的最新版本,所以,在我们的项目中有需要对低版本适配的地方需要在这里设置。同样的,我们还可以在build setting中对这一属性进行设置,两者是同步的。 Localizations:本地化,这里的功能主要是添加我们的App所支持的语言,通过上图最下面的红色圈内的【+】【-】按钮可以添加或删除不同的语种,并可以选择根据手机的设置进行不同语种的自适应。关于最下面的选择是否开启国际化,默认是开启的
Configurations:用来配置iOS项目的xcconfig文件,主要用于在几套不同的开发环境编译。xcconfig文件其实就是xcode里的config文件,本质是一个用来保存Build Settings键值对的纯文本文件。这些键值对覆盖Build Settings中的值,所以当在xcconfig文件中配置了的选项,在Build Settings中设置将失效。我们在项目中一般不会进行xcconfig文件的自定义。具体xcconfig文件是什么东东,大家可以查看:iOS之Xcconfig杂谈。估计很多新入门的iOS开发对xcconfig文件都不是很熟悉(其实我也不是很了解。。。), 但是大家可能都用过Cocoapods, 其实Cocoapods的项目配置管理很多都是依赖xcconfig文件去实现的。所以在使用Cocoapods进行导包的项目中,我们通过打开.xcworkspace文件,我们会发现project-->info-->configutations下的都有对应的配置文件,而原先没有用Cocoapods配置的则没有相关的配置文件,具体区别如下图所示。
2.2 target属性设置
在前面我提到了,target的属性设置的内容比较多,总共有general、capabilities、resource tags、 info、build setting、build phases和build rules七项,接下来我们就一个一个来了解和学习。
2.2.1 target的general属性设置
target的general属性设置界面如下图所示,主要分为六个部分,下面我们队每一部分的设置的意思进行一个解读。
Identify(标识符)栏主要定义了一些和应用发布有关的标识属性。 Display Name(App应用显示名):安装到iOS手机或iPad上App的名称。 Bundle Identifier(包标识符)是该应用的唯一ID,用来让操作系统和AppStore识别。在创建项目或者对象过程中Xcode就自行创建了包标识符,一般情况下不要修改它。 Version(外部版本号)使用户能够看到的版本号。 Build(内部版本号)开发者自己看到的版本号,以区分内部测试版本。 Signing(签名)主要是进行证书管理,在真机调试或者打包时我们都需要进行签名进行认证才可以的。这里有一个简单的使用教程,大家有需要可以戳这里:IOS的Automatically Sign功能,直接在设备上打包。 Deployment Info(部署信息)定义了一些和应用配置相关的标识属性。 Deployment Target(部署对象):用来设置支持的最低版本。这个和project的info中的一个意思,并且,这两个的设置最好是一样,如果不一样,最后的App会以target的设置为准。 Devices(设备):用来设置支持的设备,有iPhone、iPad和Universal三个选项。 Main Interface(主界面):应用启动时预加载的主界面视图。一般有两种方法: 一种是通过Main.storyboard进行启动,设置这种方法需要我们整个项目的逻辑和跳转都在Main.storyboard中完成取消stroryboard的方式启动主界面,而是通过代码的方式运行main.m的方法进行启动,并通过在AppDelegate的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中指定主界面视图进行启动。一般项目中都是采用这种方法进行的,因为一般项目中界面比较多,很多都是通过纯代码的风格进行定义的,这样方便修改和定位问题,项目的逻辑也更清晰,特别是多人合作的项目,这种风格更适合。 Device Orientation(设备方向):定义应用支持的方向。有Portrait、Upside Down、Landscape Left(横评、Home键在左)、Landscape Right几种方向。 Status Bar Style(状态栏样式) App Icons and Launch Images:应用图标和启动页面。主要设置三项:应用图标、启动图片和启动页面。具体应用图标和启动页面的大小尺寸介绍见官网:Human Interface Guidelines。 App icon Source(应用图标):对应着文件资源Assets.xcassets目录中的AppIcon中的图片,如下图所示。最右边的面板可以选择添加哪一种或哪几种设备上的图标,每一个型号的设备上的图标的尺寸是不同的。在中间有一个个的小格子,我们将所有切好的图标直接拖过来,他们会自动找到自己应该放在的格子里。这些小格子主要分为四类: Notification:通知时的图标,类似有应用相关的推送消息时,有时候需要显示本应用的图标则会显示这个尺寸的 Spotlight:搜索小图标,当在Spotlight中输入应用名,搜索结果中出现该应用时的图标就是这个尺寸的,还有设置里的图标也是这个尺寸的。 App:这就是正常的App图标,安装好之后在桌面显示的,或者分享推荐时显示的应用也是这个尺寸的图标 App store:应用商店中的显示的图标 Luanch Image Source(启动图片):同样对应着文件资源Assets.xcassets目录中的LuanchImage中的图片,设定了各种情况下的启动图片,具体界面就不截图了,和Appicon一样,我们将所有切好的图标直接拖过来,他们会自动找到自己应该放在的格子里。启动图片实际上定义了应用启动后的界面大小,所以在不同机型中我们需要做好适配,见下面的【启动页面在屏幕适配中的作用】。一款App必须设定对应设备的启动图片,否则点开应用会是一片黑白。 Luanch Screen File(启动页面文件):是一个storyboard文件,作用与Luanch Image一样,但是启动文件的优先级高于启动图片,就是说如果两个都设置了,那么启动页面以启动文件为准,如果都没有设置,则无法启动。启动页面的作用:在我们点击应用图标启动应用时,应用启动需要一定的操作时间,再启动期间,为了增强应用程序启动时的用户体验,您应该提供一个启动图像。启动图像与应用程序的首屏幕看起来非常相似。当用户在主屏幕上点击您的应用程序图标时,iPhone OS会立即显示这个启动图像。一旦准备就绪,您的应用程序就会显示它的首屏幕,来替换掉这个启动占位图像。一定要强调的是,之所以提供启动图像,是为了改善用户体验,并不是为了提供:应用程序进入体验」,比如启动动画。
启动页面在屏幕适配中的作用:每个机型,比如同时支持iPhone和iPad的程序,需要分别为iPhone跟iPad指定启动图片。当旧的iPhone 4的程序,运行在iPhone 5上面,没有iPhone 5的启动图片,就采用兼容模式,上下留黑边。当为iPhone 5指定了新的启动图片,系统就认为这个应用程序是已经适配了iPhone 5的。当旧的iPhone 5程序运行在iPhone 6上面,假如没有经过适配。旧程序自动等比放大,铺满新手机,旧程序也可以正常运行。这种方案可算是自动适配。但因为旧程序拉伸了,整体看起来有点虚,也不能更好利用大屏空间。当需要开发者手动适配的时候,跟iPhone 4过渡到iPhone 5一样,在新程序中,指定一张新的启动图片。当指定了启动图,系统就认为应用已经做好了屏幕适配,屏幕分辨率就变成应有的大小。在某机型上,如果是自动适配,比如iPhone 5,老版程序就会在屏幕上、下俩端多出俩块黑条;比如iPhone6/6plus,老版程序就会自动等比拉伸。那如何关闭自动适配?指定启动图或者使用Launch Screen File.xib,即程序使用手动适配,不会做拉伸等,但是程序内部必须已做处理,否则使用自动适配方案。 Embedded Binaries(绑定二进制文件):用来连接二进制文件,一般在使用第三方SDK的时候使用。 Linked Frameworks and Libraries(链接的框架和库):选择要链接的框架和库,既可以是SDK自带的框架,也可以是第三方框架,在Build Phases中也有类似的功能选项。
2.2.1 target的info属性设置
target的info属性设置界面如下图所示,主要分为五个部分,下面我们队每一部分的设置的意思进行一个解读。
在这一部分,最重要的就是第一部分Custom iOS Target Properties自定义iOS目标属性,其他的四个部分基本上都不怎么用,大家不用管就好了。在target的info选项卡中的五项信息与我们项目资源目录下的info.plist文件中的内容是一致,并且修改其中一个另一个会自动修改。此外,我们在2.2.1中讲到的general选项卡中的一些设置也会对应到info.plist文件中,所以这些内容都是相通的,我们修改一处,其他的地方会同步次修改。info.plist中其实加载的信息会非常多,上面是创建项目之后自动生成的一些最基本的设置选项,每一项对应的意思如下解释:
Localization native development region : 与本地化设置有关,为默认的开发语言 Executable file:程序安装包的名称 Bundle identifier:软件唯一的标识,是根据公司的标识与项目名称自动生成的,在上传和测试的时候会用到 InfoDictionary version:版本信息 Bundle name:App安装后显示的名称 Bundle OS Type code:用来标识软件包类型 Bundle versions string, short:发布的版本字符串 Bundle creator OS Type code:创建者的标识 Bundle version:应用程序版本号 Application requires iPhone environment:用于指示程序包是否只能运行在iPhone OS 系统上,默认为YES Launch screen interface file base name:欢迎界面的文件名称 Main storyboard file base name:默认情况下程序的主入口 Supported interface orientations:设置程序默认支持的方向
除此之外,我们在开发过程可能还需要添加一些其他的信息,包括一些权限的添加,网络权限、定位权限、读写联系人权限等等,应用白名单的添加等都是在这里进行配置的。关于info.plist的具体信息和内容详情参见:Xcode中的Info.plist字段列表详解。
另外四部分的简单解释:
Document Types 文档类型:定义了应用程序所能识别的文档类型,并且还可以定义在系统中显示的该类型文档的自定义图标。 Exported UTIs 导出的UTI:UTI Uniform Type Identifiers同一类型标识符。 Imported UTIs 导入的UTI: URL Types URL类型:用来定义URL以便让应用程序理解应用间交换的数据结构。可用于:IOS唤醒其他程序,程序间相互调用。例如::在URLTypes中URLSchemes中组册AAPP;在B程序中,openUrl:[NSURL urlWithString:@"AAPP:"];注意":"冒号,没有冒号是不能成唤醒另一个程序的。其次如果参数中有“&”特殊字符穿,建议对参数进行base64转换。
2.2.3 target的capabilities属性设置
target的capabilities属性设置这一块主要是一些性能设置开关选择,例如推送通知、云存储、游戏中心、后台模式等,我们选择需要的开关进行打开或者关闭,这些相应的状态都会在info.plist中进行修改。所以,同样的,我们也可以在info.plist添加一些权限或性能开关之后,在target的capabilities中也会进行相应的修改的。具体的界面如下图所示:
2.2.4 target中的Resource Tag属性设置
target中的Resource Tag选项卡主要是为项目中的资源进行添加tag分类,方便我们对齐加载顺序和加载时机进行选择和设置,即实现按需加载,在需要的时候才加载资源,属性设置界面如下图所示。这样做的好处就是可以实现如下几种资源加载形式:
初始资源的延迟加载:app有一些资源是主要功能要用到的,但在启动时并不需要。将这些资源标记为“初始需要”。操作系统在app启动时会自动下载这些资源。例如,图片编辑app有许多不常用的滤镜。 app资源的延迟加载:app有一些只在特定情景下使用的资源,当应用可能要进入这些场景时,会请求这些资源。例如,在一个有很多关卡的游戏中,用户只需要当前关卡和下一关卡的资源。 不常用资源的远程存储:app有一些很少使用的资源,当需要这些资源时会去请求它们。例如,当app第一次打开时会展示一个教程,而这个教程之后就可能不会在用到。app在第一次启动时请求教程的资源,这之后只在需要展示教程或者添加了新功能才去请求该资源。应用内购买资源的远程存储:app提供包含额外资源的应用内购买。app会在启动完成后请求已购买模块的资源。例如,用户在一个键盘app内购买了SuperGeeky表情包。应用程序会在启动完成后请求表情包的资源。第一次启动时必需资源的加载:app有一些资源只在第一次启动时需要,之后的启动不再需要。例如,app有一个只在第一次启动时展示的教程。
关于Resource Tag和按需加载的详情内容和步骤参见下面两篇文章:
On-Demand Resources Guide中文版(按需加载资源--上)
On-Demand Resources Guide中文版(按需加载资源--下)
2.2.5 target的build setting属性设置
target的build setting选项卡的是最主要的一部分编译选项设置,配置界面如下图所示,界面只是截了一部分,完整的build settings共有20项配置内容。从配置界面上看,每一项的配置都有四列,我们可以看到,从左至右的顺序分别是:Resolved列、带Target图标列、带Project图标列、iOS Default列,每一列所代表的意义如下。
Resolved列:最终确定的编译方式,无法自己设定,其结果是根据其右边三栏的选择结果以及优先级顺序来确定最后编译时采用的编译方式。在图的第二行选项卡中选择combined选项,可以直接地看到只有该栏的最后结果。带Target图标列:target的build setting配置的编译选项,可自定义。其优先级最高,一旦进行设置,则最后的编译方式以该栏的结果为准。带Project图标列:project的build setting配置的编译选项,可自定义,这一栏的结果与project中build setting选项卡中的结果是一致的,修改其中一个地方,另一处也会自动修改。其优先级介于target和default之间,当target没有设置编译选项,而该栏进行了设置时,则最后的编译方式以该栏为准。 iOS Default列:在创建项目时系统自带的默认编译选项,无法修改。优先级最低,只有当其他两栏都没有设置选项时,最后的编译方式才会以该栏为准。优先级顺序:带Target图标列 >> 带Project图标列 >> iOS Default列。
target的build setting选项卡中的每一行具体所代表的编译详情参见:Xcode 编译选项详解。
2.2.6 target的build phase属性设置
target的build phase选项卡的的主要功能是配置编译器在不同编译阶段的参数,包括编译所需的资源文件(包括代码、配置以及各种资源文件),配置界面如下图所示,主要包括四方面的内容。
Target Dependencies Target对象依赖阶段:某些Target可能依赖某个Target输出的值,这里设置依赖。依赖于其他target的输出的时候,在编译时系统会自动先编译被依赖的target,得到输出值,再编译当前target。对象依赖阶段可以让Xcode知道必须在当前选择的对象编译之编译的其它依赖对象(比如应用扩展、插件等等)。这个阶段是无法被删除的。 Compile Sources 源文件编译阶段: 是指将有哪些源代码被编译,可以通过红框中的【+】【-】按钮进行添加或删除资源来控制编译的代码文件。并且可以通过修改改阶段的Compiler Flags(编译器标识)来为每个单独文件设置其编译器编织,比如优化设置等等。 Link Binary With Libraries 链接二进制库阶段:是指编译过程中会引用哪些库文件,我们同样可以通过【+】【-】按钮进行添加或删除编译所引用的库文件。 Copy Bundle Resources 复制资源文件阶段:是指生成的product的.app内将包含哪些资源文件,同样可以通过红框中的【+】【-】按钮进行添加或删除资源来控制编译的资源文件。该阶段定义了对象中的资源文件,包括应用程序、图标、界面构造器、视频、模板等等。这些资源都会被复制到安装包的Contents/Resources文件夹下。
2.2.7 target的build rules属性设置
关于target的build rules这一块平时没有接触过,也没有进行相关的设置,网上查询了半天的资料也没有找到(囧),如果大家有相关的资料,麻烦评论里留一下,我可以补充上来。