Module compiled with Swift 5.1 cannot be imported by the Swift 5.1.2 compiler

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.


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.


Module stability and Library evolution support for closed source

[ABI]

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


Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes & Pod update - the error went away for me.