一、Xcode工作流程
常见Xcode工程里面都有些什么,Workspace文件project,podfile,config等。
1、Workspace和project
Workspace是apple公司为xcode提供的工作空间
自己创建一个NYWord.xcworkspace:
Workspace:
self:在.xcworkspace所在目录下有同名,并以.pbxproj结尾的文件group:指定目录下.xcodeproj结尾文件的路径container:在.xcworkspace当前目录下有不同名,但以.xcodeproj结尾文件absolute:绝对路径workspace中的所有project都构建在同一目录中 创建NYWord.pbxproj 文件:Project:- project和workspace管理方式不一样
- 视觉观感不一样
- 索引生成的速度不一样
- Xcode在WorkSpace工作区中 可以有多个Project项目
- 每个Project通过 Configuration配置 可生成 一个对应的Target产物
核心问题:
构建产物⼀定需要Scheme吗?
2、Target和Scheme
Scheme 定义了各个 action 应用的Target集合、以及 要使用的配置以及环境变量等
- Scheme 拥有 多种 Action:Build、Analyze、Archive、Execution、Launch、Profile、Test 等
- 指定
Product,并包含从project或workspace的⼀组⽂件。⼀个Target只能有⼀个产物。 Target产出的环境需要:LGApp.xcworkspace -scheme 的json文件来配置。通过一下命令创建Scheme json关联文件:
xcodebuild -workspace NYWord.xcworkspace -scheme NYWord -showBuildSettings -json 04
xcodebuild -project NYWord.xcodeproj -scheme NYWord -showBuildSettings -json 03
xcodebuild -project NYWord.xcodeproj -target NYWord -showBuildSettings -json 02
xcodebuild -project NYWord.xcodeproj -scheme NYWord -showBuildSettings -json configuration Debug -destination generic/ platform="iOS Simulator" 01
3、xcode内置Shell环境
每个Action 可以展开,我们可以在 执行每个Action前与后 插入脚本和 发送邮件
我们可以新建Scheme,并指定其运行环境为Release,这样 同一个Target只要在上边切换Scheme就可简单的运行在不同的配置环境中
二、Xcode 终端
- Xcode就是一个终端,它将生成产物所需要的参数(Build Settings)、Clang需要的参数,在Xcode的Shell环境中定义成环境变量(Mac中同时存在多个终端Shell环境)
//递归检测输⼊⽂件是否有变更
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES=YES
1、产出路径
2、环境变量
- 环境变量会使用关键字
Export修饰,以便外界使用Xcode会将 Build Settings 中的编译配置导出,转换成
环境变量(各种配置项在右侧栏的?选项中能找到 对应的环境变量名)验证打印环境变量(使用JS输出环境变量)
echo "$HEADER_SEARCH_PATHS--------------NYWordJS."
运行Build看到日志打印。
重要:Xcode内置常用环境变量
-
$(PROJECT_DIR):代表的是整个项目 -
${SRCROOT}:表示当前工程所在目录 -
${PODS_ROOT}:代表的是pod目录 -
${BUILD_DIR}:Products目录 -
${LOAD_PATH}:project使用的所有三方库的路径 -
$(inherited):继承上一级或依赖项的配置,让当前变量继承变量原有值- 通过CocoaPods集成的项目, $(inherited) 将会包含 Pods.xcodeproj 中的配置
- target在设置自己路径的时候如果加了这个,那么就是 继承project里设置的路径,如果不需要继承就不加,要不然乱加有可能整混导致路径错误
recursive(会在相应的目录递归搜索文件)
non-recursive (非递归)
3、跨终端Shell输出
每个终端都有其唯一的标识符,可以通过终端命令% tty,来获取当前终端标识符,通过该标识符可以进行跨终端操作
-
1>/dev/ttys000
- 1:表示正确
- > :表示
进行重定位 - /dev/ttys000:已打开的终端唯一标识符
-
原本应该打印在Xcode上的内容转为打印到终端窗口上
4、修改环境变量
.xcconfig:专门管理和配置Xcode环境变量的文件
-
新建
Configuration Settings文件 -
在 Config文件 中对环境变量进行配置(可通过include关键字导入其他Config内的配置:
#include "Debug.xcconfig") -
此时在 Build Settings 中并不能看到有什么改变,因为在一开始的图中我们就看到,
Configuration 是 Project 中用于配置 Target 的,因此 我们需要在 Project 中将新建的 Config 文件应用进去(例中只对Project的Debug环境进行应用Config文件)如图:完成上面的步骤,我们就能看到 Build Settings 中的对应项被修改为我们Config文件中的内容
-
Build Settings 中手动配置的优先级高于 Config文件
可以使用
$(inherited)继承使 Config文件 生效还可以进行条件化配置(例子中设置只在Debug模式下)
HEADER_SEARCH_PATHS[config=Debug] = "${SRCROOT}/NY"
PRODUCT_NAME = "NYWord"
注意⚠️:在Xcode 11.4及以后版本,可以使用default,来指定变量为空时的默认值:
$(BUILD_SETTING_NAME:default=value)
5、 自定义环境变量
在Config文件中可以自定义环境变量,要注意// 会当做注释符所以要做处理(引号也会被保留,不需要引号就不用添加)
在脚本中输出测试一下自定义的环境变量
此时虽然能在脚本中调用,但是并不能在代码中使用,如果想要使用可以配置在Info.plist中,然后在 代码中将 info.plist 转成字典后再使用
通过代码验证使用:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 方法一,获取文件的全部路径, 解析 info.plist
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Info.plist" ofType:nil];
NSDictionary *infoDic = [NSDictionary dictionaryWithContentsOfFile:filePath];
//方法二 直接获取
NSDictionary *infoDic2 = [NSBundle mainBundle].infoDictionary;
NSLog(@"NY_URL: %@",infoDic[@"NY_URL"]);
NSLog(@"NY_URL: %@",infoDic2[@"NY_URL"]);
}
创建命令
- 编写命令输出 Mach-O 文件路径
也是通过
${变量}来执行命令
6、 Shell脚本比对
- 常用命令介绍-基础符号
| 符号 | 作用 |
|---|---|
> | 重定向 |
& | 引用 |
| 0 | stdin 标准输入 |
| 1 | stdout 标准输出 |
| 2 | stderr 标准错误 |
- 常用命令介绍-常用指令
$指令 | 作用 |
|---|---|
| $0 | 当前脚本文件名 |
| $n | 传递给脚本或函数的参数;n是数字,表示第几个参数 |
| $# | 传递给脚本或函数的参数个数 |
| $* | 传递给脚本或函数的所有参数 |
| $@ | 传递给脚本或函数的所有参数,被双引号("")包含时,与$*稍有不同 |
$? | 获取上一个操作的结果,0表示正常 |
| $$ | 当前Shell进程ID;对于Shell脚本,就是脚本所在进程的ID |
diff:比较后边文件的内容是否相同test:用于判断,if test 判断条件等同于if [判断条件]这种写法exit 1:异常退出(0 会正常退出,1 会异常退出):会给出 Command PhaseScriptExecution failed with a nonzero exit code 的报错
创建两个文件:当
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES时,表示当Input Files中的文件有变化时才执行脚本设置在下边 Input Files 和 Output Files 中要添加 Shell脚本中要使用的文件
(我来承上启下)
来看看结果:
>&2:把前面的打印消息重定向到标准错误里面,然而我们很少把其他信息重定向到标准错误中
一般我们这样写:"某个命令" 1>/dev/null 2>&1
三、pod工程实现
1、创建pod工程依赖
创建NYAPP空工程,然后我们一步一步添加Pods.
- 在NYAPP.xcworkspace 添加NYAPP.xcodeproj 关联-可以用上面提到的代码配置关联。
- 添加TARGETS-NYAPP 到工程NYAPP.xcodeproj
3.创建一个Pods - FrameWord工程关联到 NYAPP.xcworkspace 中 (新的Pods工程)
4.添加Pods到NYAPP.xcworkspace(记住需要关闭NYAPP.xcodeproj)
删除Pods里的文件夹,然后把Pods改成Pods-NYAPP如下:
核心问题:
1.如何构建Pods与NYAPP关联呢?
如果target A要使用到target B的内容,则target A依赖target B:
Implicit Dependencies:如果target A和B在同一个project或者workspace下,则Xcode可以自动检测以来关系。当构建A之前,自动构建B;Explicit Dependencies:需要手动添加依赖关系
Xcode Target Dependencies(Target依赖)Implicit Dependencies(隐式依赖)
创建Pods-NYAPP-dummy.m文件
如果 TargetA 和 TargetB
处于同一 project 或者 workspace 下,则Xcode自动检测依赖关系,Build TargetA 之前会自动 Build TargetB
此时Build 就有 Pods-NYAPP
Explicit Dependencies(显示依赖)
在 Build Phases --> Dependencies 中手动添加的依赖,且只有在 同一project下 的Target才能添加
模仿Pods工程创建 Pods文件加添加target AFNetworking
build一下看看
PS:(要动手自己验证一下,才能得到真理)