IOS工程配置总结

2017/09/13

本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

学习IOS开发时发现IOS工程时和Android工程配置差异非常大,有很多曾经没有接触过的概念,本文主要讲解工程配置方面的概念:workspace,project,scheme,target,configuration

概念简介

workspace

workspace 是最大的集合,其可以包含多个projet,同时可以管理不同的 project 之间的关系。

workspace 的配置文件是 *.xcworkspace,其实是一个文件夹

project

project是管理所有文件,资源,以及product构建的配置信息(可以构建1个或者多个product)的仓库. 1个project包含构建product的所有元素,也管理这些元素的关系。

project包含1个或者多个target, 每1个target对应1个product,使用xcode创建1个工程,默认会创建3个target,假设工程名为CardPlayer,会有如下Target:CardPlayer,CardPlayerTests,CardPlayerUITests,这3个Target每1个都有对应的文件系统目录:

1
2
3
4
5
6
.
├── CardPlayer
├── CardPlayer.xcodeproj
├── CardPlayerTests
├── CardPlayerUITests

工程配置文件是*.xcodeproj,其实是一个文件夹,工程配置信息都在该目录下,该目录的主要内容如下所示:

1
2
3
4
5
6
7
8
CardPlayer.xcodeproj/
├── project.pbxproj
├── project.xcworkspace
│   └── contents.xcworkspacedata
└── xcshareddata
    └── xcschemes
        └── CardPlayer.xcscheme

project.pbxproj

project.pbxproj文件保存了工程配置信息:

  1. 源文件的引用: 源代码(包括头文件,和实现文件),Libraries和Frameworks,内部的和外部的,资源文件,图片文件,Interface Builder (nib)文件

  2. 在xcode中组织源文件用的groups(类似于Visual Studio里的过滤器的概念),

  3. 构建配置,比如Debug, Release,还可以新建不同的配置

  4. target,每个Target 指定了

    1. 构建的product

    2. 用于构建product的所有文件

    3. 用于构建产品的其他配置,包括对其它target的依赖,还有configuration,project级别的构建配置将应用于target的构建配置,如果target没有覆盖project的构建配置

  5. 运行应用的环境,每一个运行环境可指定:

    1. 运行或者调试时启动哪个可执行程序

    2. 执行应用时设置的环境变量

    3. 运行时的环境变量

ios的project可以独立打开,也可以位于workspace里

CardPlayer.xcscheme

我们可以使用Xcode的Schemes来指定当用户选择菜单栏Product目录下的Build, Test, Run, Profile, Anaylyze等指令执行时,

工程配置的哪个target,哪个build configuration和哪个executable configuration是激活的。

所以当用户执行Product -> Build时,会按照scheme里对Build的配置去执行,或者说Product -> Test时,会按照scheme里对Test的配置去执行

在管理scheme时,如果将某个scheme设置为共享,会产生xcshareddata/xcschemes/CardPlayer.xcscheme文件,这个文件管理scheme信息

如果没有将scheme设置为共享,不会产生CardPalyer.xcsheme文件,如果提交到git仓库,其他人将仓库代码拉下来后,将不会有scheme配置,如果使用命令行构建将会失败

创建1个工程默认会创建1个和工程名同名的scheme,如果使用cocopod创建workspace,会有2个工程,1个是我们应用的主工程,1个是Pod工程,主工程有1个sheme,Pod工程会有多个scheme,其中1个是Pod scheme,另外每个依赖的库都有1个对应的scheme

target

1个target指定了要构建的product,并且包含了从工程源文件构建product的指令。 1个target定义了单个product,它将输入组织成构建系统,包含源文件和构建product的指令。1个project可以有1个或者多个target,每个Target都可以输出1个product

构建产品的指令 在工程的 build settings 和 build phases进行设置,可以通过Xcode project editor进行检查和编辑。 target的构建指令的配置是从project的构建配置继承下来的,但是可以在xcode project editor编辑工程配置时,在target级别对构建指令进行配置。任何时候都只有1个激活的target, Xcode的scheme指定了那个激活的Target

1个target和它创建的product可以和其它target关联。 如果1个target需要依赖于其它target的输出来构建的话,则说第1个target依赖于第2个target。如果targets在同1个workspace,Xcode可以自动发现这些依赖,在这种情况下,构建时会按照需要的顺序来构建。我们说这种关系是隐式依赖。我们也可以在build phase里显示指定target的依赖关系,也可以让本以为有隐式依赖但实际没有依赖的两个target有显示依赖关系。例如,我们有可能会在同1个workspace里有1个Library,也有1个依赖于该libary的应用,Xcode可以发现这种关系,并且自动先构建Library。但是如果你真是想链接的是另1个版本的库,而不是workspace里的库,你可以创建1个在build phrase里创建显示依赖关系,这会覆盖隐式依赖

scheme

1个Xcode的scheme定义了1组要构建的target, 以及构建使用的configuration, 还有1组要执行的 tests

我们可以根据我们的需要创建任意数量的scheme, 但是每次只能有1个是激活状态。 你可以指定scheme是否保存在project中,还是在workspace中,在project中时,每1个包含该project的workspace都会看到这个scheme,如果在workspace中,则只会在那个workspace里看到。 当你选择一个激活的scheme是,你也选择了一个需要运行的目标(运行目标,是指产品基于哪个硬件架构来构建)

configuration

configuration是指构建配置,通常创建1个工程时,默认会创建2个configuration:Debug和Release,我们也可以添加configuration,部分构建指令可根据不同的configuration采用不同的构建参数,比如Code Signing Identity在Debug模式下可以使用不同的签名主体,然后工程构建配置的general面板,针对每个configuration都会有一个对应的Signing (ConfigurationName)的配置,比如Signing (Debug),另外在工程的BuildSeting里还可以为不同的Configuratio设置不同的宏。

如何配置工程

ios的工程配置文件是.xcodeproj/project.pbxproj,它是1个文本文件,但是尽量不要直接编辑,可以在xcode中打开.xcodeproj文件后,在文件管理窗口单击工程,在编辑窗口就可以看到工程配置了,如下图所示:

ios_project_config

ios的构建配置是分级别的,第1级是project级别,第2级是target级别,可以通过如下操作切换配置级别,

ios_change_configuration_level

工程级别的配置只有两项: Info 和 BuildSettings,如下所示:

ios_configuration_project_level

主target的配置项有:

  1. General tab 包括应用的DisplayName,bundle inentifier 版本, 构建号, 签名用的provisioning profile,Deploy信息等,以及链接的Frameworks和库

  2. Capabilities 是主要使用的apple的服务,像推送服务,后台运行服务

  3. Resource Tags

  4. Info 自定义的ios的目标属性 以及支持处理的文档类型 还有 url类型

  5. Build Settings 构建配置

  6. Build Phases, 包括依赖的Dependencies,需要编译的源码,需要拷贝的资源文件(比如storyboard xcasssets等文件)

  7. Build Rules 主要是规定各类型的文件的处理方式

主target的配置项如下所示:

ios_configuration_target_main_level

unit test的配置项相比主target的配置项少了Capabilities,其它都差不多,如下所示:

ios_configuration_target_uitest_level

ui test的配置项相比主target的配置项少了Capabilities,其它都差不多,如下所示:

ios_configuration_target_unittest_level

如何配置scheme

xcode中管理scheme的入口如下图所示:

ios_manage_scheme

打开管理界面后可以看到scheme列表,每个scheme可以设置为保存在project配置中还是workspace配置中,如下图所示:

ios_manage_scheme_project_workspace

打开某个scheme,就可以看到scheme的配置,每个scheme都有6个action配置,如下所示:

分别对应菜单Product下的6个菜单命令:

  1. Build 对应菜单Product下的Build命令

    Build配置主要选择Target,以及不同的target对应的Analyze, Test, Run, Profile, Archive是否要执行Build

    如下图所示:

    ios_scheme_build

  2. Run 对应菜单Product下的Run命令

    Run配置主要是配置Build Configuration以及运行时使用的Executable,并可以添加运行时的参数,环境变量,还可以决定是否用保留的数据

    配置如下所示:

    ios_scheme_run

  3. Test 对应菜单Product下的Test命令

    Test配置主要是Build Configuration,以及是否用 Coverage等收集代码覆盖率工具,还可以选择测试的target

    配置如下所示:

    ios_scheme_test

  4. Profile 对应菜单Product下的Profile命令

    Profile配置主要是Build Configuration,可执行程序等等, 用于分析性能

  5. Analyze 对应菜单Product下的Analyze命令

    Analyze配置主要是Build Configuration, 用于分析代码问题

  6. Archive 对应菜单Product下的Archive命令

    Archive配置主要是Build Configuration,Archive Name, Archive命令用于归档,产生Archive文件夹后才可以生成ipa文件

    配置如下所示:

    ios_scheme_archive

如何使用构建配置(Configuration)

我们可以在project的配置中建立Build Configuration,建立了Build Configuration后,我们可以在project的Info面板,Build Settings面板,各个Target的General面板,Info面板,Build Settings里为不同的Build Configuration设置不同的编译参数或者环境,比如为不同的Configuration设置不同的编译宏,可以在project的Build Settings的预定义宏里进行配置

如何使用命令行构建

使用命令行构建应用主要使用xcodebuild命令,有两个步骤:

  1. archive 归档

    archive命令如下所示:

    1
    xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer  -destination generic/platform=iOS -configuration Debug archive -archivePath ~/Desktop/CardPlayer
    

    归档后的文件夹为 CardPlayer.xcarchive

    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
    CardPlayer.xcarchive/
    ├── BCSymbolMaps
    │   ├── 7C32CFA1-7443-3B1C-AC8F-C54092BD708B.bcsymbolmap
    │   └── D025E19C-B50A-3D1C-94B7-54B2DD0FEDCF.bcsymbolmap
    ├── Info.plist
    ├── Products
    │   └── Applications
    │       └── CardPlayer.app
    │           ├── Assets.car
    │           ├── Base.lproj
    │           │   ├── LaunchScreen.storyboardc
    │           │   │   ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib
    │           │   │   ├── Info.plist
    │           │   │   └── UIViewController-01J-lp-oVM.nib
    │           │   └── Main.storyboardc
    │           │       ├── BYZ-38-t0r-view-8bC-Xf-vdC.nib
    │           │       ├── Info.plist
    │           │       └── UIViewController-BYZ-38-t0r.nib
    │           ├── CardPlayer
    │           ├── Info.plist
    │           ├── PkgInfo
    │           ├── _CodeSignature
    │           │   └── CodeResources
    │           ├── archived-expanded-entitlements.xcent
    │           └── embedded.mobileprovision
    └── dSYMs
        └── CardPlayer.app.dSYM
            └── Contents
                ├── Info.plist
                └── Resources
                    └── DWARF
                        └── CardPlayer
    
  2. exportArchive 将归档的文件导出成ipa文件

    exportArchive命令如下所示:

    1
    2
    xcodebuild -exportArchive -archivePath ~/Desktop/CardPlayer.xcarchive -exportPath ~/Desktop/CardPlayerIpa -exportOptionsPlist exportOptions.plist
    
    

    生成后的CardPlayer.ipa文件将位于~/Desktop/CardPlayerIpa目录下

上述两个步骤都会自动调用/usr/bin/codesign对生成的可执行程序进行签名,签名的信息保存在可执行程序二进制文件内

使用xcodebuild archive时,可以指定工程进行归档,也可以指定workspace进行归档,但是都必须指定scheme,可以选择指定configuration,也可以不指定,因为scheme配置里会指定build configuration

xcodebuild的使用帮助如下所示:

1
2
3
4
5
6
7
8
9
 xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ]
       xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
       xcodebuild -showsdks
       xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath>
       xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...]
       xcodebuild -importLocalizations -localizationPath <path> -project <projectname>

xcodebuild的使用示例如下所示:

查看ios开发sdk: xcodebuild -showsdks

查看工程的Targets, Build Configurations,Schemes: xcodebuild -list -project CardPlayer.xcodeproj

执行build action: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer build

执行analyze action: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer analyze

执行test action: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer test

执行clean action: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer clean

执行archive action: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer -destination generic/platform=iOS -configuration Debug archive -archivePath ~/Desktop/CardPlayer

将app安装到某个目录: xcodebuild -project CardPlayer.xcodeproj -scheme CardPlayer install DSTROOT=~/Desktop/MyCardPlayer

上述示例中project参数都可以换成-workspace参数,其它action还有build-for-testing,test-without-building,install-src,install,可以通过man xcodebuild命令查看详细的说明

执行exportArchive: xcodebuild -exportArchive -archivePath ~/Desktop/CardPlayer.xcarchive -exportPath ~/Desktop/CardPlayerIpa -exportOptionsPlist exportOptions.plist

还可以使用命令行安装app,不过需要安装ios-deploy工具,可以参考https://github.com/mikelupo/ios-deploy/tree/2119c1045579a51f928e16ca556c1f6e402669da,以及http://blog.csdn.net/acorld/article/details/50804495

安装App的命令如下所示:

ios-deploy -b CardPlayer.app

ios-deploy还可以上传文件 下载文件

查看某个应用的数据:

ios-deploy –bundle_id “xyz.wehere” –list

下载应用的数据:

ios-deploy –bundle_id “xyz.wehere” –download –to TestDir

使用命令行构建时可能遇到的问题

  1. 注意需将codesign在keychain access的签名证书中的访问权限设置为始终允许,可以在第1次签名时点击始终允许即可将code sign加入到永久允许名单

  2. 使用命令行构建时需要先在Shell中执行命令 security unlock-keychain -p “password” 解锁后方可执行构建

  3. 需要注意证书是否被revoke,可以在keychain access种查看证书的状态

.gitignore

典型的.gitignore配置如下所示,本配置不会忽略共享的scheme文件,所以项目源码在另一台电脑拉下来后也可用命令行直接编译:

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
# 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
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint
# *.xcscheme

## 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

¥打赏5毛

取消

感谢您的支持,我会继续努力的!

扫码支持
赏个5毛,支持我把

打开支付宝扫一扫,即可进行扫码打赏哦

本篇目录