How to set the Legacy Swift Versions for each Pod in Podfile
Asked Answered
S

8

51

I am currently setting the legacy in the Podfile to SWIFT_VERSION = 2.3, but some of the libraries I am using are Swift 3.0, which means that I need to manually set the legacy for all Swift 3.0 pods legacy to No on each pod install. How do I configure each pod version in the Podfile installer?

This is what I am setting:

post_install do |installer|
 installer.pods_project.targets.each do |target|
     target.build_configurations.each do |config|
         config.build_settings['SWIFT_VERSION'] = '2.3'
     end
 end
end

If I set config.build_settings['SWIFT_VERSION'] = '3.0', than we have issues with Swift 2.3 pods. The best solution is if we set each pod legacy version separately to avoid having to manually set it.

Squinty answered 9/11, 2016 at 6:51 Comment(0)
L
117

I found this while searching how to set the SWIFT_VERSION to 3.2 for Xcode 9.

Using the AirMapSDK which itself and multiple dependencies need 3.2 instead of 4.0 Here is an example of how to set pod specific SWIFT_VERSION for others that may come across this question.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if ['AirMapSDK', 'PhoneNumberKit', 'Lock', 'RxSwift', 'RxSwiftExt', 'RxCocoa', 'RxDataSources', 'ProtocolBuffers-Swift'].include? target.name
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '3.2'
      end
    end
  end
end

You can change the if array to specify whatever pod you need to set the version too.

Libya answered 11/10, 2017 at 14:2 Comment(2)
is it possible to fix inside podfile, NOT podspec?Newcomen
this is for using in the podfileLibya
S
11

If you need to manage multiple Swift versions for pods, you can build a mapping.

DEFAULT_SWIFT_VERSION = '4'
POD_SWIFT_VERSION_MAP = {
  'Dotzu' => '3'
}

post_install do |installer|
  installer.pods_project.targets.each do |target|
    swift_version = POD_SWIFT_VERSION_MAP[target.name] || DEFAULT_SWIFT_VERSION
    puts "Setting #{target.name} Swift version to #{swift_version}"
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = swift_version
    end
  end
end
Septemberseptembrist answered 12/10, 2018 at 7:28 Comment(1)
Wonderful answer. Works like a charm :)Lesotho
K
4

If you want to use different Swift versions, you can use this:

def pods

  pod 'PodWithSwift40'
  pod 'Pod1WithSwift42'
  pod 'Pod2WithSwift42'

end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if ['Pod1WithSiwft42', 'Pod2WithSiwft42'].include? target.name
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.2'
        end
    else
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.0'
        end
    end
  end
end
Kenti answered 27/3, 2020 at 2:2 Comment(0)
B
2

Details

  • CocoaPods v1.6.1
  • Xcode 10.2.1 (10E1001)

Ruby code in podfile

swift_versions_of_pods = { 'swiftScan' => '4.0', 'GRDB.swift' => '4.2' }
post_install do |installer|
  installer.pods_project.targets.each do |target|
    defined_swift_version = swift_versions_of_pods[target.name]
    next if defined_swift_version.blank?
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = defined_swift_version
    end
  end
end
Brockbrocken answered 15/5, 2019 at 19:46 Comment(0)
P
0

You can define an array to set Swift version nicely for all pods inside that array:

post_install do |installer|
 SWIFT_3_2_PODS = %w['AirMapSDK', 'PhoneNumberKit', 'Lock', 'RxSwift', 'RxSwiftExt', 'RxCocoa', 'RxDataSources', 'ProtocolBuffers-Swift']

 installer.pods_project.targets.each do |target|
  if SWIFT_3_2_PODS.include? target.name
      target.build_configurations.each do |config|
          config.build_settings['SWIFT_VERSION'] = '3.2'
       end
    end
  end
end
Peltz answered 12/10, 2018 at 4:28 Comment(0)
J
0

I was using this solution in CocoaPods 1.6.0.beta.2 until I realised that it does not work for iOS & tvOS projects. For example in a project using PromiseKit target.name can be PromiseKit-iOS or PromiseKit-tvOS and it is useless to check if "PromiseKit" contains such substring.

I can provide a better solution. Declare a hash with Swift versions as keys and libraries names as values:

my_project_pods_swift_versions = Hash[
  "3.0", ["PagingMenuController", "TCPickerView"],
  "4.0", ["PromiseKit"]
]

Use these functions to check if target.name contains a string like "PromiseKit", but not vice versa:

def setup_all_swift_versions(target, pods_swift_versions)
  pods_swift_versions.each { |swift_version, pods| setup_swift_version(target, pods, swift_version) }
end

def setup_swift_version(target, pods, swift_version)
  if pods.any? { |pod| target.name.include?(pod) }
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = swift_version
    end
  end
end

You should call setup_all_swift_versions inside post_install:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    setup_all_swift_versions(target, my_project_pods_swift_versions)
  end
end

Here you can find all these code snippets unified into a single code block.

Jiles answered 31/1, 2019 at 12:20 Comment(0)
M
0

Update for cocoapods 1.7+ if you have enabled multiple xcodeproj generation:

install! 'cocoapods', :generate_multiple_pod_projects => true

<Pod list section>

post_install do |installer|
    installer.pod_target_subprojects.each do |subproject|
        subproject.targets.each do |target|
            if target.name == 'OldSwiftPod'
                target.build_configurations.each do |config|
                    config.build_settings['SWIFT_VERSION'] = '3.2'
                end
            end
        end
    end
end
Mightily answered 5/6, 2019 at 13:48 Comment(0)
M
0

In case you want to set a legacy swift version to only one pod:

post_install do |installer|
  target = installer.pods_project.targets.detect {|e| e.name == 'AirMapSDK'}
  unless target.nil?
  target.build_configurations.each do |config|
  config.build_settings['SWIFT_VERSION'] = '3.2'
    end
  end
end
Moshe answered 4/9, 2020 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.