There seems to be a lot of questions and answers on how to refresh Swift Package Manager from CLI, but none on how to add or remove a dependency from CLI.
I need this as I have a lot of combinations of external dependencies that need to be handled from on single target. So I need to be able to set/remove dependencies from my fastlane lane and then resolve.
The closest I've found is the xcodeproj tools to manipulate my "project.pbxproj" file. The closest to a solution is this snippet from https://github.com/CocoaPods/Xcodeproj/issues/408#issuecomment-465942072 :
# Replace these with your values
project_location = '/path/to/MyApp.xcodeproj'
target_name = 'MyApp'
framework_root = '/framework/parent/directory'
framework_name = 'MyFramework.framework'
# Get useful variables
project = Xcodeproj::Project.open(project_location)
frameworks_group = project.groups.find { |group| group.display_name == 'Frameworks' }
target = project.targets.find { |target| target.to_s == target_name }
frameworks_build_phase = target.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
# Add new "Embed Frameworks" build phase to target
embed_frameworks_build_phase = project.new(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
embed_frameworks_build_phase.name = 'Embed Frameworks'
embed_frameworks_build_phase.symbol_dst_subfolder_spec = :frameworks
target.build_phases << embed_frameworks_build_phase
# Add framework search path to target
['Debug', 'Release'].each do |config|
paths = ['$(inherited)', framework_root]
target.build_settings(config)['FRAMEWORK_SEARCH_PATHS'] = paths
end
# Add framework to target as "Embedded Frameworks"
framework_ref = frameworks_group.new_file("#{framework_root}/#{framework_name}")
build_file = embed_frameworks_build_phase.add_file_reference(framework_ref)
frameworks_build_phase.add_file_reference(framework_ref)
build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }
# Save Xcode project
project.save
But it's not exactly what I'm looking for.
This seems to be relevant: https://www.rubydoc.info/gems/xcodeproj/Xcodeproj/Project/Object/XCRemoteSwiftPackageReference
There seem to be a lot of places a SPM is referenced in the pbxproj-file. Adding a SPM-package to a target and reviewing the change in Git reveals these four locations:
1. Under
/* Begin PBXFrameworksBuildPhase section */
2. Under
/* Begin PBXFrameworksBuildPhase section */
1B13EC1422A7971500543B8E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3. and under:
/* Begin PBXNativeTarget section */
/* ... */
1BB8572F2A44716000A81663 /* BuildTarget_AK */ = {
isa = PBXNativeTarget;
/* ... */
name = BuildTarget_AK;
packageProductDependencies = (
4. Under
/* Begin XCSwiftPackageProductDependency section */
Any leads for me here? I assume I need four different ways of setting these entries.
Update: This seems to be some code in the right direction: https://github.com/igor-makarov/xcoed/blob/564c4ae5dec1a3edb8154d33c146f776dec406bd/lib/xcoed.rb#L98