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