美文网首页ReactNative
添加iOS文件链接,操作.xcodeproj

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

作者: 我是C | 来源:发表于2017-08-11 10:09 被阅读782次

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

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

    相关文章

      网友评论

      • e46845c8b0a1:我用了你的方法,但是Unity这个文件夹没有出现在目录结构里
        我是C:project_path = File.join(File.dirname(__FILE__), ".xcodeproj文件的路径") //.xcodeproj文件的路径检查一下

        mapiGroup = project.main_group.find_subpath(File.join('目录A','A的子目录'), true)#操作工程目录,没有可以创建

        mapiGroup.set_path('../目录A/A的子目录B/B的子目录C')#源,文件的设置位置,
        这个地方稍微研究一下,不对的话就是目录位置的问题

      本文标题:添加iOS文件链接,操作.xcodeproj

      本文链接:https://www.haomeiwen.com/subject/liclrxtx.html