Cocoapods: `pod install` triggers pods to use Swift 4.2 in XCode 10

Created on 20 Sep 2018  路  21Comments  路  Source: CocoaPods/CocoaPods

[] I've read and understood the CONTRIBUTING* guidelines and have done my best effort to follow.

Report

With Xcode 10, running pod install will force all pods in workspace to use Swift 4.2, even the pod is not built for Swift 4.2. Then the workspace gets into a corrupted state where build errors cannot be removed. I have to delete the whole project and download it from our source control server.

I have tried Cocopods 1.5.3 and 1.6.0.beta.1. Both are behaving the same. Also tried to manually setting all pods back to Swift 4.0 for compilation but didn't help. I have to redownload my repo and AVOID running pod install to make my project run.

P.S. I push all pod files to my version control server.

What did you do?

Run pod install on a working workspace.

What did you expect to happen?

Install all pod dependencies correctly and the workspace should build correctly, just like in Xcode 9.

What happened instead?

'pod install' run successfully. However the workspace could not be built. Some of the pods error as Command CompileSwift failed with a nonzero exit code. Some are reporting to keywords/enums has been renamed in Swift 4.2.

CocoaPods Environment

Stack

   CocoaPods : 1.6.0.beta.1
        Ruby : ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin17]
    RubyGems : 2.5.2.3
        Host : Mac OS X 10.13.6 (17G65)
       Xcode : 10.0 (10A255)
         Git : git version 2.17.1 (Apple Git-112)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib
Repositories : facebook - https://github.com/facebook/Sonar.git @ 81e1b89b403990c678b79c620da9c0bcf8ff7d89
               master - https://github.com/CocoaPods/Specs.git @ 56daa217b3d0aed57cfcdd255cd1f7548714f396

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

cocoapods-deintegrate : 1.0.2
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.0.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0

Podfile

# Uncomment the next line to define a global platform for your project
platform :ios, '11.0'
use_frameworks!

# ignore all warnings from all pods
inhibit_all_warnings!

def common_pods
  pod 'Alamofire', '~> 4.5'
  pod 'AlamofireImage', '~> 3.3'
  pod 'AMScrollingNavbar'
  pod 'BetterSegmentedControl', '~> 0.9'

  pod 'Cache', '~> 4.1'
  pod 'Crashlytics'
  pod 'CropViewController'
  pod 'Dollar', '~> 7.1'

  pod 'Fabric'
  pod 'Hero'
  pod 'ImagePicker'
  pod 'Intercom'

  pod 'InteractiveSideMenu'
  pod 'IQKeyboardManagerSwift'
  pod 'Koyomi', :git => 'https://github.com/DaveMcKraken/Koyomi.git'
  pod 'Mixpanel-swift'
  pod 'MTBBarcodeScanner'

  pod 'netfox'
  pod 'NVActivityIndicatorView'
  pod 'OHHTTPStubs/Swift'
  pod 'PromiseKit', '~> 4.5.2'
  pod 'PromiseKit/Alamofire'

  # pod 'PocketSVG' // Not being used currently but may in future
  pod 'PopupDialog', '~> 0.6'
  pod 'RevealingSplashView'
  pod 'SearchTextField'
  pod 'SkyFloatingLabelTextField', '~> 3.0'

  pod 'Stripe'
  pod 'SwiftKeychainWrapper'
  pod 'SwiftSoup'
  pod 'UPCarouselFlowLayout', :git => 'https://github.com/andre991/UPCarouselFlowLayout.git'
  pod 'Validator'

  pod 'RxSwift',    '~> 4.0'
  pod 'RxCocoa',    '~> 4.0'
end

target 'AAA' do
  common_pods

  pod 'RxDataSources'
end

target 'AAATests' do
  common_pods
  pod 'Quick'
  pod 'RxNimble'
  pod 'RxBlocking', '~> 4.0'
  pod 'RxTest',     '~> 4.0'
end

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    # Workaround for CocoaPods issue: https://github.com/CocoaPods/CocoaPods/issues/7606
    config.build_settings.delete('CODE_SIGNING_ALLOWED')
    config.build_settings.delete('CODE_SIGNING_REQUIRED')

    # Do not need debug information for pods
    config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf'

    # Disable Code Coverage for Pods projects - only exclude ObjC pods
    config.build_settings['CLANG_ENABLE_CODE_COVERAGE'] = 'NO'
    config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = ['$(FRAMEWORK_SEARCH_PATHS)']

    config.build_settings['SWIFT_VERSION'] = '4.0'
  end
end

Most helpful comment

I was also facing the same problem and able to fix by adding swift_version in pre_install block.

pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
    s.swift_version = '4.2' unless s.swift_version
  end
end

Is there any other solution instead this.

All 21 comments

This is the default version of Swift used by Xcode 10. These pod authors must specify the Swift version they support otherwise it defaults to whatever your target is using.

Please upload a small sample demonstrating an issue.

The problem is even though I manually set all pods back to use Swift 4.0, pods are still not building. Of course also deleted all DerivedData and removed Pods folder and workspace file and do a pod install agian. Anyone has similar problems?

I will create a small project to demo the issue.

+1

Cool, please do provide sample.

I have put together a demo for the issue and provide a fix here:
https://github.com/AshleyDeng/RxSwift-MVVM

The instructions to reproduce the issue and the fix are in the Podfile.

TL;DR culprits pods are 'AMScrollingNavbar', 'Mixpanel-swift' and 'UPCarouselFlowLayout'
Do not know if there more pods triggering the same error but I am pretty sure this will fix those as well.

This compiles just fine for me, used CocoaPods 1.6.0.beta.1 (did not try 1.5.3)

screen shot 2018-09-20 at 11 21 32 pm

Also your claim that 'Mixpanel-Swift' does not appear to hold. I correctly see the version Swift 4.0 for this pod set.

screen_shot_2018-09-20_at_11_21_45_pm

The only error I got was a compilation issue:

Showing All Errors Only
/Users/dimitris/Development/ios/RxSwift-MVVM/Pods/UPCarouselFlowLayout/UPCarouselFlowLayout/UPCarouselFlowLayout.swift:49:47: Type 'UIScrollView.DecelerationRate' (aka 'CGFloat') has no member 'fast'; did you mean 'hash'?

Which the pod author should fix in order to make their pod compile with Xcode 10. I applied a fix manually and compilation worked.

For what it's worth @AshleyDeng I can reproduce this and am having a similar issue with the Eureka pod

What I think is happening is that MixPanel-swift and UPCarouselFlowLayout (and in my case Eureka) have been migrated to swift 4.2

In your project though it is still using swift 4.1 _and_ because the pod authors don't specify swift_version in their podspec they get built with swift 4.1 and the errors are goofy because it's older settings compiling newer code.

If I manually set the swift version to 4.2 on the MixPanel and UPCarouselFlowLayout targets then the whole project compiles. I also tested that if I change the Eureka podspec to define swift version and leave my project on swift 4.1 everything works as expected.

So I don't think this is a cocoa pods bug, but maybe it can help? Is there a more proactive way we can encourage pod authors to populate the swift_version setting in their podspec?

You can overcome this for now with a post_install hook. We are considering improving the API for Swift in 1.7.0.

@chrisortman

So I don't think this is a cocoa pods bug, but maybe it can help? Is there a more proactive way we can encourage pod authors to populate the swift_version setting in their podspec?

Best way is to advise pod authors to do so by filling an issue until we improve the DSL as I said above.

@dnkoutso Can you please give a sample post_install which we can define swift version for a specific pod? So i can try to overcome the issue in the meantime?

Sorry asking without searching. Here what i found for lazy ones like me :)

    if target.name == '<insert target name of your pod here>'
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.0'
        end
    end

Yes - some pods (e.g. MixPanel-swift and UPCarouselFlowLayout) are updated to use Swift 4.2 and it causes the project to fail to build. To fix it you can take a look at my sample project's Podfile or use @ergunkocak script.

We can close this issue.

@dnkoutso I'm not sure that an improved API (the most simple example of which I think is)

pod 'AwesomePod', '~> 1.2', swift_version: '4.2'

will be much of a help. It could possibly make it worse because Pod authors will think it's so easy to put this in your pod file that it is what people _should_ be doing.

I think if anything is to be done at the cocoa pods consumer level, it would be that the swift_version attribute is inferred by looking at the source files in the pod instead of a project wide setting. This path seems like there would be all sorts of edge cases to worry about though, so a more hard lined _you must set this attribute in your pod spec_ stance seems best.

yes I have an RFC in the works that captures a bit of what you are describing. I will share once its closer to be being done though.

@chrisortman when I set swift_version for mixpanel-swift I get an error:

A dependency with an external source may not specify version requirements (Mixpanel-swift).

But when I specified :git and :tag attributes for the pod in the podfile to try and alieviate the error,

My problem is that I needed to keep swift 4, but use mixpanel-swift 2.5.0 which requires swift 4.2. Fortunately the solution @dnkoutso posted above where you set the language for the pod in xcode seemed to work for me though!

hey cocoapods, how to manage cache? Ugh.

I was also facing the same problem and able to fix by adding swift_version in pre_install block.

pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
    s.swift_version = '4.2' unless s.swift_version
  end
end

Is there any other solution instead this.

This no longer seems to work after upgrading from pod version 1.5.9 to 1.6.1

 if target.name == '<insert target name of your pod here>'
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.0'
        end
    end

This would allow one to specify the the version of swift for a specific pod.

@navnathkarche is there a way to achieve the same with:

pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
    s.swift_version = '4.2' unless s.swift_version
  end
end

@newmanw your first piece of code shows the syntax for if in Ruby, so it's trivial to apply to your second piece of code:

pre_install do |installer|
    installer.analysis_result.specifications.each do |s|
        if s.name == '<insert name of your pod here>'
            s.swift_version = '4.2'
        end
    end
end
Was this page helpful?
0 / 5 - 0 ratings