Reputation: 123662
I have a framework (in this instance it's RxSwift) which I've compiled using Xcode 11.0 into the traditional RxSwift.framework
style package
This imported fine into Xcode 11.0 and also 11.1 never had any problems with it
Today, upon Apple's release of Xcode 11.2, I upgraded, and I am presented with the error:
Module compiled with Swift 5.1 cannot be imported by the Swift 5.1.2 compiler
I'm used to swift compiler mismatches, and I'm aware I can just recompile RxSwift using Xcode 11.2 and carry on, but the headline feature of Swift 5.1 was module stability.
I was under the impression that now that we have module stability, frameworks won't need to keep getting recompiled with every new Xcode release, yet this is clearly not the case.
If anyone can explain what is going on here I would much appreciate it. Is Xcode 11.2 exhibiting a bug? or did I somehow need to tell it I wanted module stability when I originally compiled with Xcode 11.0?
Upvotes: 191
Views: 172270
Reputation: 2983
I had the similar issue once I moved from xcode 13.4 to xcode 14.1 Solution was to set appropriate compiler in Xcode - Preferences - Command Line Tools
Upvotes: -1
Reputation: 1442
Sometimes can help for run app on Apple M1
try also in terminal:
arch -x86_64 pod install
Upvotes: 1
Reputation: 31
One other way I managed to fix this was just double checking the module you're using and seeing if there's an update for it. I was using ViewControllerPresentationSpy to test alert controllers in my project. I did a pod reintegrate, then pod install, to update the version from 5.1 to 6.0 as the author of that module had since released an update for it. I removed the previous module's folder in my project. Then for the new version, I was able to drag and drop the project just above all my tests after cleaning the build and going the project navigator and adding it to the Copy Files section for the VC Presentation Spy to the project.
Long story short, double check where you got your module from and check for an update and add it again to your Xcode project.
Upvotes: 1
Reputation: 114
If even after trying all the steps mentioned above, it is not resolved then try to see what all prebuild folders are present in your repo which is not directly related to your project. Delete all of them, delete pods folder and podfile.lock and clean derived data and then try to build.
It worked for me :D
Upvotes: 0
Reputation: 197
Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes & Pod update - the error went away for me.
Upvotes: 3
Reputation: 123662
OK, Turns out if you watch the WWDC video, they explain it: https://developer.apple.com/videos/play/wwdc2019/416/
You need to set the Build Settings > Build Options > Build Libraries for Distribution option to Yes in your framework's build settings, otherwise the swift compiler doesn't generate the neccessary .swiftinterface
files which are the key to future compilers being able to load your old library.
This ends up in your project.pbxproj file as:
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
After setting this flag, a framework I compiled using Xcode 11.0 (swift 5.1) was able to be used by Xcode 11.2 (swift 5.1.2) and everything appears to be working correctly.
Hopefully this question/answer will serve as a useful reference for everyone who hasn't watched all the WWDC videos
If the error still persists go to Product > Clean Build Folder and Build again.
Upvotes: 226
Reputation: 34421
Module stability and Library evolution support for closed source
Swift v5.0
introduced stable ABI
Swift v5.1
shipped Module stability
and Library evolution support
which are applicable for closed source(binary) framework(library)(framework is build separately from consumer)
Check Swift version:
Swift Language Version(SWIFT_VERSION)
To enable it you should use Xcode from v11:
Build Libraries for Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION)
Select framework target -> Build Settings -> Build Libraries for Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes
swiftc
flags:
-enable-library-evolution
-emit-module-interface
This setting generates .swiftinterface
Swift Module Interfaces (.swiftinterface)
Swift Module
uses the same approach as Objective-C module uses - precompiled binary
or Compiled Module
.
Swift Module Interfaces
is a textual representation of module's public API. It is an Swift's alternative for Objective-C's headers .h
files.
//previously
consumer(app) -> import Module -> producer(framework) .swiftmodule
//using .swiftinterface
consumer(app) -> import Module -> .swiftinterface -> producer(framework) .swiftmodule
Despite of .swiftmodule
which is changeable where you can get
Module compiled with _ cannot be imported by the _ compiler
.swiftinterface
is stable and do not need to be update when something changed(e.g. Swift version)
no assamptions
It is located in next folder
<framework_name>.framework/Modules/<framework_name>.swiftmodule
It looks like:
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
// swift-module-flags: -target x86_64-apple-ios12.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -Onone -module-name UtilsSwiftFramework
import Foundation
import Swift
@_exported import UtilsSwiftFramework
@_inheritsConvenienceInitializers @objc public class GFISClassA : ObjectiveC.NSObject {
@objc public static var shared: UtilsSwiftFramework.GFISClassA
@objc public func GFISprintHelloWorld()
@objc public func GFISprintHelloWorld(arg1: Swift.String, arg2: Swift.String)
@objc deinit
@objc override dynamic public init()
}
As you see it additionally it contains:
swift-interface-format-version
swift-compiler-version
swift-module-flags
*You can get next error if you use dynamic
without @objc
[About]
Marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported
XCFramework
[About] forces you to use it
Apple recommends to use .swiftinterface
for closed source and Swift Package Manager
[About] for open source
Upvotes: 11
Reputation: 458
I experienced this on repo after moving back to Xcode 11.3.1 from Xcode 12.3. I had summarily updated my Command Line Tools and needed to revert them to the earlier version in order to get my dependency building.
Upvotes: 1
Reputation: 36427
I ran into the same issue where I only switched branches. I deleted derived data + clean build a few times. It didn't work until I restarted Xcode
Upvotes: -3
Reputation: 119
This made my compiler error go away.
carthage bootstrap --platform ios
brew bundle
pod repo update
Upvotes: 0
Reputation: 752
You can use Carthage to add the RxSwift framework.
Basically, Carthage gives you a similar traditional RxSwift.framework style package.
Then try carthage update --no-use-binaries
.
Upvotes: -5
Reputation: 37
I had the same error importing 3rd party libraries. I fixed it using toolchains in Xcode and taking the release September 19 2019 from here https://swift.org/download/#releases. After that I had to re-import my libraries and it worked.
Upvotes: 2