Mobile Development 12 min read

Integrating Swift into an Existing iOS Client: Preparation, Framework Design, and Common Issues

This article outlines the preparation, framework redesign, and common challenges of integrating Swift into an existing Objective‑C iOS client, covering ABI stability, mixed compilation, module configuration, code standards, and future migration plans.

HaoDF Tech Team
HaoDF Tech Team
HaoDF Tech Team
Integrating Swift into an Existing iOS Client: Preparation, Framework Design, and Common Issues

Background

Swift, Apple’s first‑class language, achieved ABI stability in March 2019, meaning binaries compiled with Swift 5 or later can run on any Swift 5.0+ runtime, reducing app size and memory usage because the system provides the Swift runtime.

For Haodafu’s medical platform, adopting Swift presents a valuable opportunity, and this article explains the required preparations, basic framework design, and solutions to common Swift development issues.

Preparation for Swift Integration

Haodafu’s iOS client code dates back to 2011 and is primarily written in Objective‑C. The team first conducted a technical survey to determine the appropriate Swift version and evaluated third‑party Swift libraries, noting that the global Swift community is more active than the domestic one.

Research showed Swift offers superior development efficiency and performance, and Apple’s documentation now prioritises Swift, making migration urgent as Apple pushes Swift and SwiftUI across its platforms.

Basic Framework Design

The client uses a component‑based architecture with CocoaPods for dependency management. After Swift adoption, private libraries were selectively refactored into Swift, creating a set of Swift‑compatible base libraries while keeping unchanged components that do not require immediate migration.

For UI controls, networking, image handling, and payment libraries, refactoring impacts testing and iteration time; therefore, only essential components were updated, and new components are written in Swift by default.

After a year of gradual migration, the client now has fully Swift‑implemented features such as live streaming and message boards, with other major features using a mixed Swift/Objective‑C approach.

Problems Encountered in Swift Migration

Traditional Objective‑C projects face recurring issues such as mixed compilation, module system configuration, and code style enforcement.

How to mix Swift and Objective‑C in the main app or modular components

Module system setup

Ensuring Swift code conforms to style guidelines

1. Swift and Objective‑C Mixed Compilation

When adding the first Swift file to an Objective‑C target, Xcode prompts to create a bridging header; simply click “Create”.

In a Swift file, import an Objective‑C class using #import in the bridging header. Conversely, an Objective‑C file can import Swift symbols with import "ProductModuleName-Swift.h" , where ProductModuleName is the target name.

For modular components, configure CocoaPods by adding s.pod_target_xcconfig = {'DEFINES_MODULE' => 'YES'} , generate an umbrella.h (or create one) that includes the Objective‑C headers to be exposed, and then import the module in Swift with import Module .

2. Module System

2.1 LLVM Module System

Apple introduced the LLVM module system in 2012, replacing traditional #include directives with import statements (e.g., import std.io ), which provides a complete semantic description, improves compile‑time scalability, reduces fragmentation, and offers better tooling support.

Provides a full semantic description of a framework

Improves compile‑time scalability by avoiding repeated header parsing

Reduces fragmentation; each module is processed once

Tool‑friendly; compilers can obtain richer module metadata

2.2 modulemap File

The modulemap file describes the structure of a framework or library; the default filename is module.modulemap . Using the umbrella header keyword, all .h files in HDFIMComponent-umbrella.h are imported.

The umbrella header acts as a master header file; for example:

#import <UIKit/UIKit.h>
#import <UIKit/UIViewController.h>
#import <UIKit/UILabel.h>
#import <UIKit/UIButton.h>
#import <UIKit/UIDatePicker.h>

2.3 Swift Module

Each target (framework or app) is a Swift module. Importing a module with import brings its namespace and public/open symbols into scope, providing an independent access‑control domain.

A namespace matching the module name

An independent access‑control scope

This explains why classes defined in different Swift files can be used without explicit include statements.

3. Swift Code Standards

To ensure consistent style, Haodafu introduced SwiftLint, an open‑source linter from Realm, integrated with SonarQube for reporting. SwiftLint scans the codebase, enforces formatting rules, and helps keep “code smell” count at zero.

Future Plans

Swift’s popularity is rising, and Apple’s push makes it essential for future iOS development. Haodafu plans to upgrade Swift versions annually, adopt Swift Package Manager to replace CocoaPods, and move towards declarative UI.

Future articles will dive deeper into Swift Package Manager integration, Swift‑Objective‑C interop pitfalls, and SwiftLint integration with SonarQube.

Author

Tao Qingwei – iOS engineer at Haodafu, responsible for component architecture, core libraries, client stability, and Swift adoption.

References

August Headline: Holiday season in the programming language world

Swift ABI Stability

Apple Importing Objective‑C into Swift

CocoaPods umbrella.h

Swift programming language

SwiftLint

Access Control

mobile developmentiOSCocoaPodsSwiftModule SystemObjective-CSwiftLint
HaoDF Tech Team
Written by

HaoDF Tech Team

HaoDF Online tech practice and sharing—join us to discuss and help create quality healthcare through technology.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.