-
-
Save ratazzi/f6d9217654d6605450a0 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env ruby | |
| require 'rubygems' | |
| require 'xcodeproj' | |
| name = 'test_copy' | |
| proj = Xcodeproj::Project.open('test.xcodeproj') | |
| src_target = proj.targets.find { |item| item.to_s == 'test' } | |
| # create target | |
| target = proj.new_target(src_target.symbol_type, name, src_target.platform_name, src_target.deployment_target) | |
| target.product_name = name | |
| # create scheme | |
| scheme = Xcodeproj::XCScheme.new | |
| scheme.add_build_target(target) | |
| scheme.set_launch_target(target) | |
| scheme.save_as(proj_path, name) | |
| # copy build_configurations | |
| target.build_configurations.map do |item| | |
| item.build_settings.update(src_target.build_settings(item.name)) | |
| end | |
| # copy build_phases | |
| phases = src_target.build_phases.reject { |x| x.instance_of? Xcodeproj::Project::Object::PBXShellScriptBuildPhase }.collect(&:class) | |
| phases.each do |klass| | |
| src = src_target.build_phases.find { |x| x.instance_of? klass } | |
| dst = target.build_phases.find { |x| x.instance_of? klass } | |
| unless dst | |
| dst ||= proj.new(klass) | |
| target.build_phases << dst | |
| end | |
| dst.files.map { |x| x.remove_from_project } | |
| src.files.each do |f| | |
| file_ref = proj.new(Xcodeproj::Project::Object::PBXFileReference) | |
| file_ref.name = f.file_ref.name | |
| file_ref.path = f.file_ref.path | |
| file_ref.source_tree = f.file_ref.source_tree | |
| file_ref.last_known_file_type = f.file_ref.last_known_file_type | |
| file_ref.fileEncoding = f.file_ref.fileEncoding | |
| begin | |
| file_ref.move(f.file_ref.parent) | |
| rescue | |
| end | |
| build_file = proj.new(Xcodeproj::Project::Object::PBXBuildFile) | |
| build_file.file_ref = f.file_ref | |
| dst.files << build_file | |
| end | |
| end | |
| # add files | |
| classes = proj.main_group.groups.find { |x| x.to_s == 'Group' }.groups.find { |x| x.name == 'Classes' } | |
| sources = target.build_phases.find { |x| x.instance_of? Xcodeproj::Project::Object::PBXSourcesBuildPhase } | |
| file_ref = classes.new_file('test.m') | |
| build_file = proj.new(Xcodeproj::Project::Object::PBXBuildFile) | |
| build_file.file_ref = file_ref | |
| sources.files << build_file | |
| proj.save |
@prathmeshranaut
This method can make the xcode 9.4.1 crash when you delete the new target in xcode. I meet the error. Maybe we can't use the same uuid file in different target.
can we duplicate xcworkspace targets using this approach ?
This was very useful, thank you. For those just joining us, the bit under "# add files" is an example in case you have new files to add to the dst target, it's not "working code". And yes, it's proj.name not proj_name.
I had issues with PBXFileReference for some reason its parameters where nil, so I needed to introduce conditions before assigning the values and it works. It is strange thought that I used this script before and added just condition for fileEncoding and it worked. So if anyone has explanation how properties like name, path, source_tree, last_known_file_type became nil I would really appreciate. In docs name can be missing: the name of the reference, often not present. but what about others.
@prathmeshranaut
I tried your suggestion but I get error: