iOS xcodeproj脚本关联文件(RN离线包和图片)


公司的RN项目,一直以来是通过RN端,执行npm install和npm run build手动打包之后,将bundle和图片传给客户端,客户端人工将bundle和图片拖入到工程中,提交到git上面,再通过自动化打包平台Jenkins执行groovy脚本命令,进行打包生成二维码。
显而易见,这样做的坏处太多了。

*每次发版,RN都要将包传给客户端,客户端和前端的工作柔和在一起了。
*长期向git上提交bundle和图片文件(虽然项目bundle只有1.5M),对服务器压力大。

所以RN和客户端各自在git上提交维护各自的代码,都统一到打包平台打包显得很有必要。(虽然这还不是最佳的方式-->RN嵌套到主工程中,但在平常开发中更节省时间和人力,也离最佳的方式更近一步了)。

通过查看打包平台Groovy jenkins脚本文件,找到了解决办法:在脚本中执行打包命令之前,

exportArchiveCommond = [
  ['.', 'xcodebuild -exportArchive -archivePath build/工程名称.xcarchive -exportPath build -exportOptionsPlist ./opt.plist'],
 ]

先去git拉取React Native代码到iOS工程根目录下。并执行React Native打包命令。在RN工程中根目录下要新建output文件夹,存放iOS和Android的bundle和图片文件。

npm install,npm run build

此时已经生成iOS的main.jsbundle文件和asset图片文件夹,要将此文件拷贝到iOS工程目录下。再执行iOS打包命令,此时自认为main.jsbundle文件和assets文件就打入到iOS工程中。脚本文件如下。

IOSBuildPlugin{
 // 基础配置
 app_type = ['工程名称']
 env_tag = ['test1','test2', 'test3', 'test6', 'release']
 app_versionName = '2.1.0'  //版本号
 bundleID='helloworld' //一般取bundle identifier最后一个点后面的三位
 IPANAME='XHINFO.ipa' //打出来.ipa文件的名字
 outputDir = 'build'
 preBuild = [
    ['.', 'rm -rf RNProject'],//删除RN工程
    ['.', 'git clone -b RNProject-2.1.0.TEST http://www.baidu.com:8080/xhgroup/RNProject.git'],//从git拉取指定分支iOS工程根目录下
 ]
 // 根据环境修改配置文件 test1,test2,release环境的切换,原理是在工程中autopackage文件夹下分别创建test1,test2,test6文件夹,里面分别放入对应的环境文件。
   modifyFileConfig = [
     '工程名称':[
       'test1':[
       ['autopackage/config/test1/Setting.h' , 'Source/Setting.h'],
       ],

       'test2':[
       ['autopackage/config/test2/Setting.h' , 'Source/Setting.h'],
       ],
     
     'release':[
       ['autopackage/config/release/Setting.h' ,'Source/Setting.h'],
     ]
     ]
   ]
   // 打包命令
  compileCommond = [
    ['.', 'mkdir -p ./RNProject/output/{android,ios}'],//在RN工程目录下新建output文件夹,目录下再建ios和android文件夹。
    ['./RNProject', 'npm install'],//执行react-native安装命令
    ['./RNProject', 'npm run build'],//执行打React Native里面包命令
    ['.', 'cp RNProject/output/ios/main.jsbundle ReactComponent/main.jsbundle'],//拷贝main.jsbundle文件到iOS工程指定目录下
    ['.', 'cp -r RNProject/output/ios/bundle/assets ReactComponent/'],//拷贝图片文件夹assets到iOS工程指定目录下
    ['.', 'pod install --verbose --no-repo-update'],//iOS pod install
    ['.', 'xcodebuild -workspace iOS工程名称.xcworkspace -scheme iOS工程名 archive -archivePath build/iOS工程名称.xcarchive'],//执行iOS打包命令

 ]

 exportArchiveCommond = [
  ['.', 'xcodebuild -exportArchive -archivePath build/iOS工程名称.xcarchive -exportPath build -exportOptionsPlist ./opt.plist'],
 ]//导出.ipa文件

}

此时打出来的包,闪退,在打包平台本地运行发现。main.jsbundle和图片assets文件夹存在工程物理目录下并不在工程文件中。在工程文件中的Build Phases的Copy Bundle Resources文件中根本没有main.jsbundle文件和assets文件夹。

iOS xcodeproj脚本关联文件(RN离线包和图片)_第1张图片
image

iOS xcodeproj脚本关联文件(RN离线包和图片)_第2张图片
image

iOS xcodeproj脚本关联文件(RN离线包和图片)_第3张图片
image

通过查阅资料得知:此时main.jsbundle和assets文件虽然存在于iOS工程中,但是并没有产生关联,编译器并不会识别这两个文件。平常拖入一个文件到工程中时,通常需要如下操作,选择创建Group或者folder references两种方式中的一种。
iOS xcodeproj脚本关联文件(RN离线包和图片)_第4张图片
image

但是RN离线bundle和assets文件夹必须以folder references方式加入工程中。手动拖入之后assets文件夹为蓝色。Build Phases文件中也含有main.jsbundle和assets文件夹了。

iOS xcodeproj脚本关联文件(RN离线包和图片)_第5张图片
image

下面是RN打离线包和手动拖入工程方式:

  • 在工程根目录下执行打包命令,比如react-native bundle --entry-file demo/index.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false,请参考上面命令说明,根据自己的情况进行修改再执行。注意要先保证bundle文件夹存在。
    iOS xcodeproj脚本关联文件(RN离线包和图片)_第6张图片
    image

    *在xcode中添加assets【必须用Create folder references的方式,添加完是蓝色文件夹图标】和index.ios.jsbundle
    iOS xcodeproj脚本关联文件(RN离线包和图片)_第7张图片
    image

此时需要做的就是在打包平台用脚本将main.jsbundle和assets图片文件夹和iOS工程关联起来。

正好ruby的开源框架xcodeproj可以关联文件,cocoapods就是使用ruby关联文件。相关文件语法参考使用代码为 Xcode 工程添加文件

使用 Xcodeproj

Xcodeproj 是一个使用 Ruby 来创建和修改 Xcode 工程文件的工具. 我找到它的原因是 Cocoapods 也通过 Ruby 代码向 Xcode 工程中添加文件, 所以我在 Cocoapods 中找到了这一组件.
在最开始尝试使用这个工具的时候, 发现它的文档是极其糟糕. 根本无法直接在文档找到向 Xcode 工程中添加文件的方法, 这一简单的需求并没有明确的写在文档中, 这令我十分的不理解.
这个组件的主要功能不就是向工程中添加文件么? 为什么没有写在文档中, 而我所做的就是不断的阅读这个组件的源代码, 尝试理解 project.pbxproj 中的东西到底都是什么. 而在这期间, 有几个非常重要的问题需要我们理解.
Target
Group
FileRef

Target
Target 到底是什么, 我在以前的 iOS 开发的工作中并没有仔细地考虑这一个问题, 直到我遇到这一需求时, 我在尝试理解这背后的意义.
A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product. Projects can contain one or more targets, each of which produces one product.
Target 指定了一个用于产品(product), 并且包含了从工程中的一些文件中构建产品的命令.
这些命令使用构建设置(build settings)和构建阶段(build phases)的方式来组织, 我们可以在 Xcode 编辑器中改变这些设置.
Group
Group 这个概念和我们平时经常说的 folder 文件夹有很大的差别, 文件夹在我们的日常使用时是一直所接触到的, 而对于 Group, 如果你不使用 Xcode 来编程(不是很清楚别的 IDE 是否有这个功能)的话, 这个概念距离你太远了.
Group 其实是 Xcode 中用来组织文件的一种方式, 它对文件系统没有任何影响, 无论你创建或者删除一个 Group, 都不会导致 folder 的增加或者移除. 当然如果在你删除时选择 Move to Trash 就是另外一说了.
在 Group 中的文件的关系, 不会与 folder 中的有什么冲突, 它只是 Xcode 为你提供的一种分离关注的方式而已. 但是, 我一般会在开发过程中将不同的模块分到不同的 Group 和 folder 中便于整理.
Group 之间的关系, 也是在 project.pbxproj 中定义的, 这个文件中包含了 Xcode 工程中所有 File 和 Group 的关系, 如果你大致浏览过这个文件的话, 你就会对我所说的有所了解.
Group 在我们的工程中就是黄色的文件夹, 而 Folder 是蓝色的文件夹(一般在 Xcode 工程中, 我们不会使用 Folder).
FileRef
FileRef 其实就是 File Reference 的缩写, 当你从 Xcode 中删除一个文件的时候, 它会弹出这样的提示框.
而其中的 Remove Reference 选项并不会将这个文件移除到垃圾桶, 而只是会将这个文件的引用从 Xcode 的工程文件中删除.
如果你曾经看过 Build Phases 中的内容, 你会发现
如果删除的是 .h 文件, 它会从 Build Phases 中的 Headers 部分删除
如果删除的是 .m 文件, 它会从 Build Phases 中的 Compile Source 部分删除
但是文件还是会在原来的地方, 因为 Xcode 中所加入到工程的只是文件的一个引用 — File Ref.
添加文件

我们已经基本了解了阅读这一篇博客所需要的全部知识, 接下来, 我们就需要来分析一下向 Xcode 工程中添加文件所需要的几个步骤.
当我们生成一堆 Objective-C 代码时, 我们的第一步是要将这些文件拖入 Xcode 工程中, 这时 Xcode 会弹出视图询问你是创建 Groups 还是 Folder references, 并询问你要加入到哪个 Target 中.

当选择创建 Groups 时, Xcode 就会把 .h 文件加入 Build Phases 中的 Header, 把 .m 文件加入 Compile Sources 中, 并创建一个黄色的文件夹.
当选择创建 Folder references 时, Xcode 会把所有的文件加入 Build Phases 中的 Copy Bundles Resources, 不进行任何的编译, 然后创建一个蓝色的文件夹.
我们现在就来使用代码来模拟将文件加入 Xcode 中, 选择 Create Groups 并且添加到指定 Target 的全过程.
在这里我们需要使用 Ruby 的开源框架 xcodeproj 这个框架是著名的开源框架 Cocoapods 的一个组件.

创建 Group

lib/xcodeproj/project/object/group.rb
在获取 Target 之后, 需要创建或者获取一个文件即将被添加进去的 group, 我一般使用 find_subpath 这个方法
def find_subpath(path, should_create = false)
它能比较快捷的根据路径名寻找 group, 如果当前的 group 不存在, 它还会递归地创建(可选).
group = project.main_group.find_subpath(File.join('DKNightVersion', 'Pod', 'Classes', 'UIKit'), true)
因为这个方法是一个 group 的实例方法, 所以先通过 main_group 获取主 group, 然后再调用这个方法, 最后会返回指定的 group. 在工程中创建这样一种的结构.

在成功获取之后还需要把 group 的 source_tree 设置成 'SOURCE_ROOT', 这样在加入到 Build Phases 的时候, 它会从工程文件的根目录下开始寻找你所添加的文件, 不会出现一些非常奇怪的问题.
group.set_source_tree('SOURCE_ROOT')
向 group 中添加文件

lib/xcodeproj/project/object/group.rb
我们在获取 group 之后就可以向其中添加文件了. 在这时使用 new_reference 方法, 为文件创建一个 FileRef 添加到 group 中.
file_ref = group.new_reference(file_path)
这样这个文件就添加到了 group 中, 会出现在工程中的导航栏中.
但是这个文件并没有被添加到 Build Phases 中, 无论你是编译还是作为资源来使用, Xcode 都会提示你无法找到这个文件. 我们还需要把这个文件加入到 Build Phases 中.
将文件加入 Build Phases

lib/xcodeproj/project/object/native_target.rb
在前面获取到的 Target 在这一步就开始起了作用, 我们需要获取 Target 的 Build Phase 并将在上面添加的文件添加到 Build Phase 中.
target.add_file_references([file_ref])
add_file_references 就负责把一组 FileRef 添加到对应的 Build Phases 中, source_build_phase headers_build_phase resource_build_phase framework_build_phase 在 GUI 中你可以找到这四者对应的 section.
而 add_file_references 方法自动为你把 FileRef 添加到合适的 phase 中.
但是从 Build Phase 中移除文件就需要手动获取这些 *_build_phase 然后从中调用 remove_reference 来删除文件或者资源.
target.source_build_phase.remove_file_reference(file_ref)
target.headers_build_phase.remove_file_refernece(file_ref)
保存 Project

在最后, 我们只需要调用 save 方法来保存整个工程就好了.
project.save
总结

project = Xcodeproj::Project.open(path)
target = project.targets.first
group = project.main_group.find_subpath(File.join('DKNightVersion', 'Pod', 'Classes', 'UIKit'), true)
group.set_source_tree('SOURCE_ROOT')
file_ref = group.new_reference(file_path)
target.add_file_references([file_ref])
project.save

  • 安装RubyMine软件
  • 搭配ruby环境。通过在终端输入gem install xcodeproj这是可能会报错。
ERROR:  SSL verification error at depth 1: unable to get local issuer certificate (20)
ERROR:  You must add /O=Digital Signature Trust Co./CN=DST Root CA X3 to your local trusted store
Fetching: xcodeproj-1.5.3.gem (100%)
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
iOS xcodeproj脚本关联文件(RN离线包和图片)_第8张图片
image
  • 因为我们在安装cocoapods时将gem sources设置为了https://gems.ruby-china.org/,此时我们需要将gem镜像修改为https://rubygems.org/
  • 移除现有的镜像,gem sources --remove https://gems.ruby-china.org/和修改镜像为https://rubygems.org/,此时有可能还报错误。
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
    
  • sudo gem install xcodeproj有可能还会报错。
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
  • 在stackoverflow搜到的解释是这样的,This is happening because Apple has enabled rootless on the new install,也就是说在10.11系统上苹果已经启用无根的安装。在这种情况下,如果你使用如下的命令:sudo gem install -n /usr/local/bin xcodeproj 执行sudo gem install -n /usr/local/bin xcodeproj,致此ruby环境已经搭配好。


    iOS xcodeproj脚本关联文件(RN离线包和图片)_第9张图片
    image

接下来运用ruby脚本写一个添加文件的测试工程。

  • 新建一个空的iOS工程
  • 用RubyMine(安装RubyMine.dmg之后的免费破解地址为:http://idea.imsxm.com/)新建rubyzero.rb文件。
    iOS xcodeproj脚本关联文件(RN离线包和图片)_第10张图片
    image

    *目前只是人为的将Jasper文件夹(里面有main.jsbundle文件和assets图片文件夹),并Build Phases里面的copy Bundle Resources文件里面并不存在main.jsbundle和asset文件。
    iOS xcodeproj脚本关联文件(RN离线包和图片)_第11张图片
    image

直接上ruby代码如下。参考添加iOS文件链接,操作。xcodeproj

require 'xcodeproj'  #导入

project_path = File.join(File.dirname(__FILE__), "./RubyZeroProject.xcodeproj")
project = Xcodeproj::Project.open(project_path)
target = project.targets.first
mapiGroup = project.main_group.find_subpath(File.join('RubyZeroProject','Jasper'), true)
mapiGroup.set_source_tree('')
mapiGroup.set_path('./Jasper') #相对于你放代码的文件夹
#移除文件链接
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
  aGroup.files.each do |file|
#        if file.real_path.to_s.end_with?(".m", ".mm") then
#            aTarget.source_build_phase.remove_file_reference(file)
#            elsif file.real_path.to_s.end_with?(".plist") then
    aTarget.resources_build_phase.remove_file_reference(file)
#        end
  end

  aGroup.groups.each do |group|
    removeBuildPhaseFilesRecursively(aTarget, group)
  end
end
#添加文件链接
def addFilesToGroup(aTarget, aGroup)
  Dir.foreach(aGroup.real_path) do |entry|
    filePath = File.join(aGroup.real_path, entry)
    # 过滤目录和.DS_Store文件
    if entry != ".DS_Store" && !filePath.to_s.end_with?(".meta") &&entry != "." &&entry != ".."then

      # 向group中增加文件引用
      fileReference = aGroup.new_reference(filePath)
      # 如果不是头文件则继续增加到Build Phase中,PB文件需要加编译标志
      #            if filePath.to_s.end_with?("pbobjc.m", "pbobjc.mm") then
      #                aTarget.add_file_references([fileReference], '-fno-objc-arc')
      #                elsif filePath.to_s.end_with?(".m", ".mm") then
      #                aTarget.source_build_phase.add_file_reference(fileReference, true)
      #                elsif filePath.to_s.end_with?(".plist") then
      aTarget.resources_build_phase.add_file_reference(fileReference, true)
      #            end
    end
  end
end
if !mapiGroup.empty? then
  removeBuildPhaseFilesRecursively(target,mapiGroup)
  mapiGroup.clear()
end

addFilesToGroup(target, mapiGroup)
project.save

运行ruby脚本之后达到了我们想要的效果。
image

理论知识:

require 'xcodeproj'  #导入
project_path = File.join(File.dirname(__FILE__), "./RubyZeroProject.xcodeproj")
project = Xcodeproj::Project.open(project_path)
target = project.targets.first

1)./RubyZeroProject.xcodeproj 是工程文件名,主要看test.rb文件和./RubyZeroProject.xcodeproj目录关系,同级就./ 上一级../
2)找到target,一般都是first

mapiGroup = project.main_group.find_subpath(File.join('RubyZeroProject','Jasper'), true)
mapiGroup.set_source_tree('')
mapiGroup.set_path('./Jasper') #相对于你放代码的文件夹

1.)project.main_group.find_subpath(File.join('RubyZeroProject','Jasper'), true) 找到你想放在项目里的位置,如果没有Unity这个文件夹,会自动创建.
2.)mapiGroup.set_source_tree('') 设置group,相当于这个一个文件夹,文件放在这个文件夹里.
3).mapiGroup.set_path 设置源路径,比如你的包打在了Unity这个文件夹里,然后工程会对应的去Jasper这个里找文件,然后链接在项目里

#移除文件链接
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
    aGroup.files.each do |file|
#        if file.real_path.to_s.end_with?(".m", ".mm") then
#            aTarget.source_build_phase.remove_file_reference(file)
#            elsif file.real_path.to_s.end_with?(".plist") then
            aTarget.resources_build_phase.remove_file_reference(file)
#        end
    end
    
    aGroup.groups.each do |group|
        removeBuildPhaseFilesRecursively(aTarget, group)
    end
end

由于每次添加的时候都需要移除该Group里的文件链接,所以aTarget.resources_build_phase.remove_file_reference,移除资源文件的链接(因为我这里只有资源文件,没有.m .mm )

#添加文件链接
def addFilesToGroup(aTarget, aGroup)
    Dir.foreach(aGroup.real_path) do |entry|
        filePath = File.join(aGroup.real_path, entry)
        # 过滤目录和.DS_Store文件
        if entry != ".DS_Store" && !filePath.to_s.end_with?(".meta") &&entry != "." &&entry != ".."then

            # 向group中增加文件引用
            fileReference = aGroup.new_reference(filePath)
            # 如果不是头文件则继续增加到Build Phase中,PB文件需要加编译标志
#            if filePath.to_s.end_with?("pbobjc.m", "pbobjc.mm") then
#                aTarget.add_file_references([fileReference], '-fno-objc-arc')
#                elsif filePath.to_s.end_with?(".m", ".mm") then
#                aTarget.source_build_phase.add_file_reference(fileReference, true)
#                elsif filePath.to_s.end_with?(".plist") then
                aTarget.resources_build_phase.add_file_reference(fileReference, true)
#            end
        end
    end
end

因为我这里只有资源文件,所以aTarget.resources_build_phase.add_file_reference(fileReference, true)

if !mapiGroup.empty? then
    removeBuildPhaseFilesRecursively(target,mapiGroup)
    mapiGroup.clear()
end

addFilesToGroup(target, mapiGroup)
project.save

写的demo能够成功将main.jsbundle和assets文件关联起来。需要重新编写ruby文件放到项目xcodeproj同一级目录上。AddFileToProject.rb文件内容如下。

require 'xcodeproj'  #导入

project_path = File.join(File.dirname(__FILE__), "./iOS工程名称.xcodeproj")
project = Xcodeproj::Project.open(project_path)
target = project.targets.first
mapiGroup = project.main_group.find_subpath(File.join('ReactBundle'), true)//存放bundle和图片
mapiGroup.set_source_tree('')
mapiGroup.set_path('ReactBundle') #相对于你放代码的文件夹
#移除文件链接
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
  aGroup.files.each do |file|
#        if file.real_path.to_s.end_with?(".m", ".mm") then
#            aTarget.source_build_phase.remove_file_reference(file)
#            elsif file.real_path.to_s.end_with?(".plist") then
    aTarget.resources_build_phase.remove_file_reference(file)
#        end
  end

  aGroup.groups.each do |group|
    removeBuildPhaseFilesRecursively(aTarget, group)
  end
end
#添加文件链接
def addFilesToGroup(aTarget, aGroup)
  Dir.foreach(aGroup.real_path) do |entry|
    filePath = File.join(aGroup.real_path, entry)
    # 过滤目录和.DS_Store文件
    if entry != ".DS_Store" && !filePath.to_s.end_with?(".meta") &&entry != "." &&entry != ".."then

      # 向group中增加文件引用
      fileReference = aGroup.new_reference(filePath)
      # 如果不是头文件则继续增加到Build Phase中,PB文件需要加编译标志
      #            if filePath.to_s.end_with?("pbobjc.m", "pbobjc.mm") then
      #                aTarget.add_file_references([fileReference], '-fno-objc-arc')
      #                elsif filePath.to_s.end_with?(".m", ".mm") then
      #                aTarget.source_build_phase.add_file_reference(fileReference, true)
      #                elsif filePath.to_s.end_with?(".plist") then
      aTarget.resources_build_phase.add_file_reference(fileReference, true)
      #            end
    end
  end
end
if !mapiGroup.empty? then
  removeBuildPhaseFilesRecursively(target,mapiGroup)
  mapiGroup.clear()
end

addFilesToGroup(target, mapiGroup)
project.save
print "执行替换文件成功!"

JenkinsFile文件如下:

IOSBuildPlugin{
 // 基础配置
 app_type = ['工程名称']
 env_tag = ['test1','test2', 'test3', 'test6', 'release']
 app_versionName = '2.1.0'  //版本号
 bundleID='helloworld' //一般取bundle identifier最后一个点后面的三位
 IPANAME='XHINFO.ipa' //打出来.ipa文件的名字
 outputDir = 'build'
 preBuild = [
    ['.', 'rm -rf RNProject'],//删除RN工程
    ['.', 'git clone -b RNProject-2.1.0.TEST http://www.baidu.com:8080/xhgroup/RNProject.git'],//从git拉取指定分支iOS工程根目录下
 ]
 // 根据环境修改配置文件 test1,test2,release环境的切换,原理是在工程中autopackage文件夹下分别创建test1,test2,test6文件夹,里面分别放入对应的环境文件。
   modifyFileConfig = [
     '工程名称':[
       'test1':[
       ['autopackage/config/test1/Setting.h' , 'Source/Setting.h'],
       ],

       'test2':[
       ['autopackage/config/test2/Setting.h' , 'Source/Setting.h'],
       ],
     
     'release':[
       ['autopackage/config/release/Setting.h' ,'Source/Setting.h'],
     ]
     ]
   ]
   // 打包命令
  compileCommond = [
    ['.', 'mkdir -p ./RNProject/output/{android,ios}'],//在RN工程目录下新建output文件夹,目录下再建ios和android文件夹。
    ['./RNProject', 'npm install'],//执行react-native安装命令
    ['./RNProject', 'npm run build'],//执行打React Native里面包命令
    ['.', 'cp RNProject/output/ios/main.jsbundle ReactComponent/main.jsbundle'],//拷贝main.jsbundle文件到iOS工程指定目录下
    ['.', 'cp -r RNProject/output/ios/bundle/assets ReactComponent/'],//拷贝图片文件夹assets到iOS工程指定目录下
    ['.', 'ruby AddFileToProject.rb'],//重要的一步,执行ruby脚本给main.jsbundle和图片增加iOS工程关联
    ['.', 'pod install --verbose --no-repo-update'],//iOS pod install
    ['.', 'xcodebuild -workspace iOS工程名称.xcworkspace -scheme iOS工程名 archive -archivePath build/iOS工程名称.xcarchive'],//执行iOS打包命令

 ]

 exportArchiveCommond = [
  ['.', 'xcodebuild -exportArchive -archivePath build/iOS工程名称.xcarchive -exportPath build -exportOptionsPlist ./opt.plist'],
 ]//导出.ipa文件

能够成功在Jenkinles打包平台打包。

你可能感兴趣的:(iOS xcodeproj脚本关联文件(RN离线包和图片))