添加iOS文件链接,操作.xcodeproj

背景:最近在做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,然后看一下目录结构

04B18072-7FDE-4F49-9ABE-77D723BB3EE9.png

下面我上代码看一下:

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

5B21C440-36D4-4C11-98B7-4F9AC99E9AFA.png


提供一份完整的代码和注释

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 文件.之后每次打包后会立马重组目录链接,很效率

如果有错误,望指正,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 说明本次redis集群安装在rhel6.8 64位机器上,redis版本为3.2.8,redis的gem文件版本为...
    读或写阅读 14,660评论 3 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • CocoaPods 是什么? CocoaPods 是一个负责管理 iOS 项目中第三方开源库的工具。CocoaPo...
    朝洋阅读 25,662评论 3 51
  • 【转载】曾梦想仗剑走天涯 1.Xcode IDE概览 说明:从左到右,依次是“导航窗格(Navigator)->边...
    06a6a973d7ab阅读 3,826评论 2 20
  • 1.Xcode IDE概览 说明:从左到右,依次是“导航窗格(Navigator)->边列(Gutter)->焦点...
    小地阅读 5,357评论 0 9