Mastering Swift‑Objective‑C Mixed Compilation in JD’s iOS App: A Practical Guide
This article details JD's journey from Objective‑C to Swift, explaining ABI stability, module stability, library evolution, and step‑by‑step configurations for mixed Swift‑Objective‑C compilation at both project and component levels, including build‑setting tweaks and runtime loading solutions.
Background
Since Swift was introduced, JD has gradually migrated its iOS app from Objective‑C to Swift. After ABI stability, module stability and library evolution became available, JD launched the first mixed‑language version of the JD App in July 2020 and completed component‑level mixed compilation.
ABI Stability
Swift 5.0 provides ABI stability, allowing binaries compiled with Swift 5.0+ to run on any Swift 5.0+ runtime. This reduces startup time, improves performance and lowers memory usage. ABI stability is present in iOS 12.2, macOS 10.14.4 and later.
Module Stability
Swift 5.1 introduces module stability, enabling modules built with different compiler versions to be used together. The .swiftmodule file is replaced by a textual .swiftinterface that describes public APIs, making cross‑version integration seamless.
Library Evolution
Swift 5.1 also adds library evolution, allowing binary frameworks to evolve without breaking existing clients. Public or open symbols must be marked @objc and inherit from an Objective‑C class when accessed from ObjC.
Mixed‑Compilation Approaches
Project‑level mixed compilation
JD’s app is a CocoaPods‑based componentized project. Two scenarios are considered: the main project mixing Swift and ObjC, and each component mixing Swift and ObjC.
Swift calls ObjC (project)
Create a bridging header (
-Bridging-Header.h) and set
SWIFT_OBJC_BRIDGING_HEADERto its path.
Add the required ObjC headers to the bridging header.
ObjC calls Swift (project)
Enable
DEFINES_MODULE = YESin build settings.
Import the generated
ProjectName‑Swift.h(
#import <ProjectName/ProjectName‑Swift.h>for frameworks or
#import "ProjectName‑Swift.h"for static libraries).
Mark Swift classes as
public/
openand expose methods with
@objc.
Component‑level mixed compilation
Add Swift source files to the component without a bridging header, list them in the podspec’s
source_files, and configure ObjC‑to‑Swift and Swift‑to‑ObjC communication as described above.
Build Settings for Swift Support
Static linking issues are solved by adding the Swift library paths to
Library Search Paths:
$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)
$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
Dynamic loading problems on iOS 12.2+ require adding
/usr/lib/swiftto the first entry of
Runpath Search Paths. On iOS <12.2, set
Always Embed Swift Standard Librariesto
YES.
Summary of Communication Schemes
All communication patterns—Swift↔ObjC inside a component, between components, and in the main project—are summarized in the final diagram.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
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.