Implementing Swift Mixed Compilation in the JD App: ABI Stability, Module Stability, Library Evolution, and Integration Strategies
This article details JD's transition to Swift mixed compilation, covering ABI stability, module stability, library evolution, the required Xcode configurations, bridging techniques for Swift‑ObjC interaction, component‑level mixing approaches, and solutions to static and dynamic linking issues across iOS versions.
Background – Since Swift’s introduction, JD has gradually shifted from Objective‑C to Swift, culminating in the launch of its first mixed‑language version in July 2020 after ABI stability, module stability, and library evolution became available.
ABI Stability (Swift 5.0) – Provides binary compatibility across Swift 5.0+ runtimes, improving launch speed, runtime performance, and memory usage. It is built into iOS 12.2, watchOS 5.2, macOS 10.14.4 and later.
Module Stability (Swift 5.1) – Allows modules compiled with different Swift compiler versions to be used together. The .swiftmodule format is replaced by a textual .swiftinterface file that contains all public APIs, enabling cross‑version compatibility.
Library Evolution (Swift 5.1) – Enables binary‑compatible updates of libraries. When enabled, API changes are automatically resilient, preventing runtime crashes for downstream consumers.
Mixed‑Compilation Approaches – JD’s app is a Cocoapods‑based componentized project. Two main scenarios are considered: (1) mixing at the main‑project level and (2) mixing within individual components. Different handling is required for Swift‑to‑ObjC and ObjC‑to‑Swift calls.
3.1 Swift calling ObjC (Main Project) – Create a bridging header ( -Bridging-Header.h ), set SWIFT_OBJC_BRIDGING_HEADER in Build Settings, and list the required ObjC headers.
3.2 ObjC calling Swift (Main Project) – Import the generated Swift header ( ProjectName‑Swift.h ) in ObjC files, ensure SWIFT_OBJC_INTERFACE_HEADER_NAME is correct, and use forward declarations when needed.
3.3 Swift calling ObjC (Component) – Direct bridging is not possible inside a single framework; instead, expose ObjC headers via the component’s umbrella header and set DEFINES_MODULE = YES in the podspec.
3.4 ObjC calling Swift (Component) – Import the Swift interface header ( <Component/Component‑Swift.h> for frameworks or "Component‑Swift.h" for static libraries) and mark Swift APIs with @objc and public/open visibility.
Component‑Level Mixing Implementation – Add Swift files without a bridging header, update source_files in the podspec, and configure ObjC‑to‑Swift and Swift‑to‑ObjC communication as described. Ensure DEFINES_MODULE = YES and that Swift classes are public.
Module Map Example
framework module STStaticBasicStableModule {
umbrella header "STStaticBasicStableModule-umbrella.h"
export *
module * { export * }
}
module STStaticBasicStableModule.Swift {
header "STStaticBasicStableModule-Swift.h"
requires objc
}Swift Module Loading – The compiler searches for .swiftmodule files inside .framework/Modules/ . Example loader code is shown in the article.
Component‑Level Communication Diagrams – The article includes several PNG diagrams illustrating the flow of ObjC↔Swift calls within and between components.
JD Main‑Project Support
Static Linking Issues – Add Swift library paths to Library Search Paths : $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
Dynamic Library Loading Issues – For iOS 12.2+ add /usr/lib/swift to the first entry of Runpath Search Paths . For iOS <12.2 set Always Embed Swift Standard Libraries = YES .
One‑Click Configuration – Adding an empty Swift file to the project triggers Xcode to auto‑configure many of the required settings.
Communication Scheme Summary – The article concludes with a consolidated diagram summarizing all mixed‑compilation communication patterns across components and the main project.
Authors : Wang Yanchang, Yao Qi, Lin Xiaofeng
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.