From e0321e9286c7d5877983fad2607c1d7b69d06c68 Mon Sep 17 00:00:00 2001 From: Dimitris Koutsogiorgas Date: Fri, 23 Jul 2021 20:58:06 +0300 Subject: [PATCH] Add support for adding and removing on demand resources. --- CHANGELOG.md | 5 ++ lib/xcodeproj/project/object/native_target.rb | 43 ++++++++++++++ spec/project/object/native_target_spec.rb | 59 ++++++++++++++++++- 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebd1aaa11..be793d655 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ##### Enhancements +* Add support for adding and removing on demand resources. + [JunyiXie](https://github.com/JunyiXie) + [Dimitris Koutsogiorgas](https://github.com/dnkoutso) + [#844](https://github.com/CocoaPods/Xcodeproj/pull/844) + * Add `platform_filters` support for `PBXBuildPhase`. [Dimitris Koutsogiorgas](https://github.com/dnkoutso) [#838](https://github.com/CocoaPods/Xcodeproj/issues/838) diff --git a/lib/xcodeproj/project/object/native_target.rb b/lib/xcodeproj/project/object/native_target.rb index b9d36641f..0ad703289 100644 --- a/lib/xcodeproj/project/object/native_target.rb +++ b/lib/xcodeproj/project/object/native_target.rb @@ -552,6 +552,49 @@ def add_resources(resource_file_references) end end + # Adds on demand resources to the resources build phase of the target. + # + # @param {String => [Array]} on_demand_resource_tag_files + # the files references of the on demand resources to add to the target keyed by the tag. + # + # @return [void] + # + def add_on_demand_resources(on_demand_resource_tag_files) + on_demand_resource_tag_files.each do |tag, file_refs| + file_refs.each do |file_ref| + if resources_build_phase.include?(file_ref) + existing_build_file = resources_build_phase.build_file(file_ref) + existing_build_file.settings ||= {} + existing_build_file.settings['ASSET_TAGS'] ||= [] + existing_build_file.settings['ASSET_TAGS'] << tag + existing_build_file.settings['ASSET_TAGS'].uniq! + next + end + build_file = resources_build_phase.add_file_reference(file_ref, true) + build_file.settings = (build_file.settings ||= {}).merge('ASSET_TAGS' => [tag]) + end + end + end + + # Remove on demand resources from the resources build phase of the target. + # + # @param {String => [Array]} on_demand_resource_tag_files + # the files references of the on demand resources to add to the target keyed by the tag. + # + # @return [void] + # + def remove_on_demand_resources(on_demand_resource_tag_files) + on_demand_resource_tag_files.each do |tag, file_refs| + file_refs.each do |file_ref| + build_file = resources_build_phase.build_file(file_ref) + next if build_file.nil? + asset_tags = build_file.settings['ASSET_TAGS'] + asset_tags.delete(tag) + resources_build_phase.remove_file_reference(file_ref) if asset_tags.empty? + end + end + end + # Finds or creates the headers build phase of the target. # # @note A target should have only one headers build phase. diff --git a/spec/project/object/native_target_spec.rb b/spec/project/object/native_target_spec.rb index 8e5d59b0c..a82b8e7a6 100644 --- a/spec/project/object/native_target_spec.rb +++ b/spec/project/object/native_target_spec.rb @@ -947,7 +947,64 @@ module ProjectSpecs build_files.first.settings.should.be.nil end - it 'de-duplicates added sources files' do + it 'adds on demand resources' do + apple_ref = @project.main_group.new_file('apple.png') + orange_ref = @project.main_group.new_file('orange.png') + bear_ref = @project.main_group.new_file('bear.png') + frog_ref = @project.main_group.new_file('frog.png') + on_demand_resources = { 'fruits' => [apple_ref, orange_ref], 'animals' => [bear_ref, frog_ref], 'mixed' => [apple_ref, bear_ref] } + @target.add_on_demand_resources(on_demand_resources) + build_files = @target.resources_build_phase.files + build_files.count.should == 4 + build_files.map(&:display_name).should == %w(apple.png orange.png bear.png frog.png) + build_files[0].settings.should == { 'ASSET_TAGS' => %w(fruits mixed) } + build_files[1].settings.should == { 'ASSET_TAGS' => ['fruits'] } + build_files[2].settings.should == { 'ASSET_TAGS' => %w(animals mixed) } + build_files[3].settings.should == { 'ASSET_TAGS' => ['animals'] } + end + + it 'does not add a duplicate file reference to the resources build phase for on demand resources' do + apple_ref = @project.main_group.new_file('apple.png') + @target.resources_build_phase.add_file_reference(apple_ref) + on_demand_resources = { 'fruits' => [apple_ref] } + @target.add_on_demand_resources(on_demand_resources) + build_files = @target.resources_build_phase.files + build_files.count.should == 1 + build_files.map(&:display_name).should == %w(apple.png) + build_files[0].settings.should == { 'ASSET_TAGS' => %w(fruits) } + end + + it 'removes on demand resources' do + apple_ref = @project.main_group.new_file('apple.png') + orange_ref = @project.main_group.new_file('orange.png') + bear_ref = @project.main_group.new_file('bear.png') + frog_ref = @project.main_group.new_file('frog.png') + on_demand_resources = { 'fruits' => [apple_ref, orange_ref], 'animals' => [bear_ref, frog_ref], 'mixed' => [apple_ref, bear_ref] } + @target.add_on_demand_resources(on_demand_resources) + @target.resources_build_phase.files.count.should == 4 + @target.remove_on_demand_resources(on_demand_resources) + @target.resources_build_phase.files.count.should == 0 + end + + it 'removes specific on demand resource tag' do + apple_ref = @project.main_group.new_file('apple.png') + orange_ref = @project.main_group.new_file('orange.png') + bear_ref = @project.main_group.new_file('bear.png') + frog_ref = @project.main_group.new_file('frog.png') + on_demand_resources = { 'fruits' => [apple_ref, orange_ref], 'animals' => [bear_ref, frog_ref], 'mixed' => [apple_ref, bear_ref] } + @target.add_on_demand_resources(on_demand_resources) + @target.resources_build_phase.files.count.should == 4 + @target.remove_on_demand_resources('fruits' => [apple_ref]) + build_files = @target.resources_build_phase.files + build_files.count.should == 4 + build_files.map(&:display_name).should == %w(apple.png orange.png bear.png frog.png) + build_files[0].settings.should == { 'ASSET_TAGS' => ['mixed'] } + build_files[1].settings.should == { 'ASSET_TAGS' => ['fruits'] } + build_files[2].settings.should == { 'ASSET_TAGS' => %w(animals mixed) } + build_files[3].settings.should == { 'ASSET_TAGS' => ['animals'] } + end + + it 'de-duplicates added source files' do ref = @project.main_group.new_file('Class.h') new_build_files = @target.add_file_references([ref], '-fobjc-arc') @target.add_file_references([ref], '-fobjc-arc')