背景:最近在做RN相关的内容,每次打bundle包之后,都是手动拖入到项目里,感觉很麻烦.于是乎想到了管理文件链接的. xcodeproj;在此记录一下
. xcodeproj 是一个plist文件也就是一个特殊的xml文件,右键其他方式选编辑器打开看一下
7F6502EF-5AC9-4550-81FF-95A9F8260B3C.png每个文件链接有着相关联的关系,具体的可以看通过Xcodeproj深入探究Xcode工程文件
1.PBXBuildFile PBXBuildFile是文件类,被PBXBuildPhase等作为文件包含或被引用的资源
2.PBXFileReference PBXFileReference用于跟踪项目引用的每一个外部文件,比如源代码文件、资源文件、库文件、生成目标文件等。
3.PBXGroup PBXGroup用于组文件,或者嵌套组
在这里我们需要使用 Ruby 的开源框架 xcodeproj 这个框架是著名的开源框架 Cocoapods 的一个组件.
首先创建一个ruby文件,我们这里叫test.rb
,然后看一下目录结构
下面我上代码看一下:
require 'xcodeproj' #导入
project_path = File.join(File.dirname(__FILE__), "./tetetetetetete.xcodeproj")
project = Xcodeproj::Project.open(project_path)
target = project.targets.first
1)./tetetetetetete.xcodeproj 是工程文件名,主要看test.rb文件和./tetetetetetete.xcodeproj目录关系,同级就./
上一级../
2)找到target,一般都是first
mapiGroup = project.main_group.find_subpath(File.join('tetetetetetete','Unity'), true)
mapiGroup.set_source_tree('<group>')
mapiGroup.set_path('./Unity') #相对于你放代码的文件夹
1.)project.main_group.find_subpath(File.join('tetetetetetete','Unity'), true)
找到你想放在项目里的位置,如果没有Unity
这个文件夹,会自动创建.project的工程目录
2.)mapiGroup.set_source_tree('<group>')
设置group,
3).mapiGroup.set_path
设置源路径,比如你的包打在了Unity这个文件夹里,然后工程会对应的去Unity这个里找文件,然后链接在项目里,物理目录相对于tetetetetetete.xcodeproj目录
#移除文件链接
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
接下来向文件放RN 的相关文件
BA9DD8F2-6E6D-4452-B106-7E847E0D6711.png执行 ruby test.rb
,现在文件就会链接到工程里,跟手动添加的效果一样
然后看看Bundle Resources
提供一份完整的代码和注释
require 'xcodeproj'
#相对于 ruby文件 .xcodeproj 的路径
project_path = File.join(File.dirname(__FILE__), "../xxx/xx/xx.xcodeproj")
project = Xcodeproj::Project.open(project_path)
target = project.targets.first
#第一个参数,相对于.xcodeproj 项目根目录,一定要和工程里的根目录名字相同
#第二个参数,相对工程里的目录
mapiGroup = project.main_group.find_subpath(File.join('xx','Bundle'), true)#创建工程目录,没有可以创建
mapiGroup.set_source_tree('<group>')
#源,相对于.xcodeproj路径,提供给项目实体文件的路径
mapiGroup.set_path('../xx/Bundle/bundle')
#移除索引
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
aGroup.files.each do |file|
aTarget.resources_build_phase.remove_file_reference(file)
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)
aTarget.resources_build_phase.add_file_reference(fileReference, true)
end
end
end
if !mapiGroup.empty? then
removeBuildPhaseFilesRecursively(target,mapiGroup)
mapiGroup.clear()
end
addFilesToGroup(target, mapiGroup)
puts "重组目录结构..."
project.save
大功告成,
现在步骤是,先打包bundle文件,然后利用npm post
钩子,执行ruby 文件.之后每次打包后会立马重组目录链接,很效率
如果有错误,望指正,谢谢!
网友评论
mapiGroup = project.main_group.find_subpath(File.join('目录A','A的子目录'), true)#操作工程目录,没有可以创建
mapiGroup.set_path('../目录A/A的子目录B/B的子目录C')#源,文件的设置位置,
这个地方稍微研究一下,不对的话就是目录位置的问题