1.一些基本概念

Workspace:
简单来说,Workspace就是一个容器,在该容器中可以存放多个你创建的Xcode Project, 以及其他的项目中需要使用到的文件。

使用Workspace的好处有:
1),扩展项目的可视域,即可以在多个项目之间跳转,重构,一个项目可以使用另一个项目的输 出。Workspace会负责各个Project之间提供各种相互依赖的关系;
2),多个项目之间共享Build目录。

Project:
指一个项目,该项目会负责管理生成一个或者多个软件产品的全部文件和配置,一个Project可以包含多个Target。

Target:
一个Target是指在一个Project中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。

Scheme:
一个定义好构建过程的Target成为一个Scheme。可在Scheme中定义的Target的构建过程有:Build/Run/Test/Profile/Analyze/Archive

BuildSetting:
配置产品的Build设置,比方说,使用哪个Architectures?使用哪个版本的SDK?。在Xcode Project中,有Project级别的Build Setting,也有Target级别的Build Setting。Build一个产品时一定是针对某个Target的,因此,XCode中总是优先选择Target的Build Setting,如果Target没有配置,则会使用Project的Build Setting。

First Header Second Header
Content from cell 1 Content from cell 2
Content in the first column Content in the second column
名称 意义 备注
$(TARGET_NAME) Target名字
$(PRODUCT_NAME) Product名字
$(SRCROOT) 工程文件(xxx.xcodeproj)所在目录
$(BUILT_PRODUCTS_DIR) Products输出目录
$(CURRENT_PROJECT_VERSION) 当前项目版本号
$(CONTENTS_FOLDER_PATH) xxx.app目录

workspace拷贝库工程资源bundle到主工程

  在最近的项目开发任务中遇到一个问题,在一个workspace中,主工程A依赖的工程B中有资源文件,通过shell脚本新建的资源bundle C拷贝到主工程A中,这个过程在运行时不存在问题,却在archive时出现了问题,拷贝到xx.app中的是资源bundle C的快捷方式。

  经排查,运行时product目录如下:
/Users/uxxx/Library/Developer/Xcode/DerivedData/pxxx-fpafzsejajqwoggtyxizyelluxjd/Build/Products/Debug-iphoneos

而在archive时,product目录如下:
/Users/uxxx/Library/Developer/Xcode/DerivedData/pxxx-fpafzsejajqwoggtyxizyelluxjd/Build/Intermediates/ArchiveIntermediates/pxxx/BuildProductsPath/Release-iphoneos

但是其中的product全部属于快捷方式,真正的product目标存储在临时目录中:
/Users/uxxx/Library/Developer/Xcode/DerivedData/pxxx-fpafzsejajqwoggtyxizyelluxjd/Build/Intermediates/ArchiveIntermediates/pxxx/IntermediateBuildFilesPath/UninstalledProducts/iphoneos

因此拷贝脚本在编译时拷贝正常,却在archive时出现异常。

  于是乎,一开始想到配2套拷贝脚本,但是转念一想,这样可以达到目标但是比较麻烦。所以另寻他法,最终确定的思路是,通过快捷方式找到目标文件的真实路径,然后进行拷贝。求助脚本大神获得了获取真实文件路径的脚本,剩下的内容就是脚本的事情了。

脚本内容如下:

1
#获取文件原始路径方法,如果是快捷方式,返回真实路径,否则保留原路径
function getOriginal()
{
    [[ `ls -lt $1 | head -1|awk '{print $10}'` == "->" ]] && Original = `ls -lt $1 | head -1|awk '{print $11}'`|| Original = $1
}

#步骤一:获取xxx.bundle真实路径
getOriginal "$BUILT_PRODUCTS_DIR/xxx.bundle"
#步骤二:copy xxx.bundle到xxx.app中
cp -R -f $Original $BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/

#如果有多个文件拷贝,重复步骤一和步骤二即可

保存好的脚本文件(CopyBundle.sh)添加到工程目录中,然后在主工程对应的target-Build Phases-New Run Script Phase
添加新的shell脚本,其中代码如下:

1
#注意脚本文件路径,xxx为需要根据工程补全的路径
sh ${SRCROOT}/xxx/CopyBundle.sh

至此,就是大功告成了!