编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • Android提升进阶

  • iOS开发和进阶

    • README
    • ObjC编程入门

    • Swift编程入门

    • iOS入门到精通

      • iOS入门到精通案例
      • UIKit框架原理探索
      • UIViewController
      • 项目工程面板说明
      • 通信实践和设计思想
      • 网络请求和数据解析
      • 多线程实践和原理
      • Swift和OC混编开发
        • 04.混编之桥接文件
          • 4.1 建立头文件桥接
          • 4.2 混编中找不到头文件
        • 05.混编开发调用技巧
          • 5.1 OC调用Swift
          • 5.2 Swift调用OC
          • 5.3 遇到的坑说明
        • 06.Framework混编
          • 6.1 背景说明一下
          • 6.2 头文件导入方式
          • 6.3 配置modulemap
        • 参考
      • Swift版SnapKit布局
      • 开发SDK实践设计
      • iOS经验类笔记积累
  • Web开发和进阶

  • Linux应用开发

  • Apps
  • iOS开发和进阶
  • iOS入门到精通
杨充
2025-04-22
目录

Swift和OC混编开发

# 13.Swift和OC混编开发

# 目录介绍

  • 04.混编之桥接文件
    • 4.1 建立头文件桥接
    • 4.2 混编中找不到头文件
  • 05.混编开发调用技巧
    • 5.1 OC调用Swift
    • 5.2 Swift调用OC
    • 5.3 遇到的坑说明
  • 06.Framework混编
    • 6.1 背景说明一下
    • 6.2 头文件导入方式
    • 6.3 配置modulemap

# 04.混编之桥接文件

# 4.1 建立头文件桥接

建立一个 Header 头文件,将它放置在自己想要放置的文件下。比如在混编App开发的时候,应用层用Swift,一些基础库用OC,当Swift想去调用OC可以采用头文件桥接这种方式。

在APP开发中,swift和OC文件可以通过桥接的方式互相调用。特别是swift语言调用OC时,把OC文件直接拖到工程中,xcode会自动生成桥接文件。

但是在编写framework文件时会发现拖动到工程中,不但没有生成桥接文件反而报了错;解决此类问题使用module.modulemap文件显得特别方便。

# 4.2 混编中找不到头文件

报错:三方库头文件 import 报错 '**.h' file not found with include

#import <MJExtension.h>
1

解决方案:这也是一类问题,使用不规范的写法导入基础组件头文件,在混编过程中就会直接报错,修改 import 写法即可解决:

#import "MJExtension.h"
//或
#import <MJExtension/MJExtension.h>
1
2
3

# 05.混编开发调用技巧

# 5.1 OC调用Swift

OC想要调用Swift,Swift类必须用@objc + public修饰,否则无法访问。继承自NSObject或其子类

在OC文件#import <项目名/项目名-Swift.h>文件,这个文件是编译器自动生成的。比如:#import "ProductName/ProductModuleName-Swift.h"

# 5.2 Swift调用OC

在 ProductModuleName-Bridging-Header.h 桥接文件中引入Swift需要调用的OC头文件

在这个桥接文件里面引用你想暴露给Swift调用类的头文件。说明:这个桥接文件需要自己手动创建

# 5.3 遇到的坑说明

坑1: 在OC类中引用Swift编译之后的头文件,必须采用"ProductName/ProductModuleName-Swift.h"方式,使用ProductModuleName-Swift.h方式,会提示找不到该文件

坑2: 如果未设置Objective-C Bridging Header,引用ProductName/ProductModuleName-Swift.h头文件之后依然无法在OC类中调用Swift类

因为设置Objective-C Bridging Header后,才会编译Swift类到ProductModuleName-Swift.h中。设置Objective-C Bridging Header后Swift类被翻译成OC类,才可以被OC调用

坑3: 设置Objective-C Bridging Header后编译报错using bridging headers with framework targets is unsupported,解决方案就是修改ProductModuleName.h这个文件名称为其他名称,比如:ProductModuleNameHeader.h

# 06.Framework混编

# 6.1 背景说明一下

随着swift ABI的稳定,越来越多的开发者开始使用swift语言开发项目,但是由于大部分工具库也还是使用OC写的,因此我们不得不需要在项目中采用swift与oc混编。

在开发app项目时,swift与oc混编其实很容易,xcode会自动为我们建立一个桥接文件,这样我们就很容易的在swift中调用oc的方法或类对象。

但是在开发framework的时候,xcode不会为我们建立这个桥接文件,因此我们在framework中也就不能采用桥接的方式进行混编了。

# 6.2 头文件导入方式

第一种:也是最简单的一种,就是将oc的头文件暴露出来,并在framework的头文件中导入。(缺点:我们不想对外暴露的类或方法,不得不暴露出去)

具体参考:https://www.cnblogs.com/zbblog/p/16228840.html

# 6.3 配置modulemap

第二种:配置modulemap,这个方法可以避免我们不得不对外暴露我们的oc类。

第一步:在项目中创建module.modulemap文件,具体内容如下:

//这里我们定义了一个 WecardPaySDK 的模块,也就是提供给swift导入的模块名称。
module WecardPaySDK {
    
    //使用了一个umbrella header文件"HeaderPrivate.h",该文件用于导入Swift和Objective-C的私有头文件。
    umbrella header "HeaderPrivate.h"

    // 这里的路径是相对于module.modulemap的所在目录
    header "WecardPay.h"
    
    //在这个模块中,使用了export关键字,表示将模块中的所有内容都导出,使其可供其他模块或应用程序使用。
    export *
}
1
2
3
4
5
6
7
8
9
10
11
12

第二步:配置Swift Compiler - Search Paths Import Paths。这里是为了告诉编译器,我们自定义的module所在路径,这里指定了项目的根目录:$(SRCROOT)

具体参考:https://blog.csdn.net/qq26983255/article/details/89107699

# 参考

  • iOS 学习笔记:https://github.com/xiusl/ObjectiveC_Day
  • OC与Swift实现framework内混编:https://juejin.cn/post/7343691521600471040?searchId=20250422111304F5DECFF620425F268EC9
  • Swift与OC混编:https://juejin.cn/post/6964610478219722765?searchId=20250422111304F5DECFF620425F268EC9
  • Swift和OC混编:https://juejin.cn/post/7031738486084337700
  • OC-Swift 混编踩坑总结:https://juejin.cn/post/7070430587701444638
上次更新: 2026/06/10, 11:13:41
多线程实践和原理
Swift版SnapKit布局

← 多线程实践和原理 Swift版SnapKit布局→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式