-
-
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 File encoding error is caused when the script tries copying storyboard files which do not have a file encoding.
how do you fix this and give them file encoding?
# Copy the build phases
src_target.build_phases.each do |phase|
target.build_phases << phase
end
I tried your suggestion but I get error:
undefined method `new_file' for nil:NilClass (NoMethodError)
@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.
Line 24-54 can be replaced by:
This fixes and .fileEncoding issues. File encoding error is caused when the script tries copying storyboard files which do not have a file encoding.