当前位置: 首页 > news >正文

Swift项目生成Framework流程以及与OC的区别

一. 引言

Swift 已经成为 iOS 开发的主流语言,在实际项目中,打包成 Framework(二进制框架) 已经是模块化、组件化开发的常见需求。

对于 Objective-C 而言,制作 Framework 几乎是轻车熟路的流程:只需设置好暴露头文件,一切都能顺利调用。

但当我们用 Swift 来生成 Framework 时,对于新手而言往往会遇到各种让人困惑的问题——

比如:

  • 源码似乎被“暴露”出去了?
  • 明明设置了暴露文件却依旧无法访问?
  • public、internal 的边界到底是如何决定的?

在本篇文章中,我们将以一个“播放器”为例,从零开始讲解 Swift 项目生成 Framework 的完整流程,并重点分析它与 Objective-C 在模块暴露机制、访问控制以及编译产物结构上的区别。希望读完之后,你能彻底搞懂 Swift Framework 打包背后的逻辑。

二. 生成步骤

接下来我们就以一个“播放器”为例,演示如何从零开始创建并打包一个 Swift Framework。

在这个示例中,我们将创建一个名为 PlayerFramework 的框架,用来模拟一个简单的播放器逻辑。

其中会包含:

  • 两个公开方法:play() 和 pause() —— 对外提供播放与暂停功能。
  • 一个私有方法:loadMediaFile()加载资源,仅供框架内部使用。

完成后,我们会将生成的 .framework 文件导入到另一个示例项目中进行测试,确保外部调用正常、私有方法不可访问。

2.1 创建Framework工程

对于创建工程的步骤OC项目和Swift项目到的确是没有什么区别。

新建一个Project,菜单栏选择“iOS” ,向下拉到“Framework & Library”然后选择Framework。

然后输入 “Product Name” 选择 “Team”等等信息,Most important of all ,“Language”要选择Swift,不然就该去看OC教程了。

创建好的工程目录结构如下:

1. 最上面的 PlayerFramework 工程的根目录。

2. PlayerFramework 文件夹 是源码文件,这个目录才是 真正的代码与配置文件所在位置,一般包括:

  • PlayerFramework.h
  • Swift 源文件(比如稍后你要放的 PlayerHelper.swift)
  • Info.plist(框架的配置文件)

PlayerFramework.h:

这个是 Umbrella Header(总头文件),在 Objective-C 框架中非常重要,用于声明哪些符号对外暴露。

但在 纯 Swift Framework 中,这个文件基本不会起作用,

因为 Swift 的符号暴露完全由关键字 public / internal / private 控制。

3. PlayerFramework( 图书馆图标)

这是 编译产物文件夹(Build Products),也就是编译完成后生成的真正的 .framework 文件。

每次你在 Xcode 里 Build 后,系统会在这里生成一份新的 Framework。

它一般包含:

  • 一个 “📖 图书图标” 的文件:这是实际的二进制可执行文件(PlayerFramework 本体),内部就是 Swift 编译器输出的 .o 链接产物。
  • 一个 Resources/ 文件夹:存放资源文件(图片、plist、json等),如果你的框架带有资源就会放在这里。
这个文件夹并不是你自己维护的,而是 Xcode 自动生成的  编译产物

2.2 构建PlayeHelper类

接下来,我们来创建一个示例类 —— PlayerHelper,用来模拟播放器的核心逻辑。在这个例子中,我们会定义两个对外暴露的公共方法:play() 和 pause(),同时在内部实现一个私有的加载方法 loadMediaFile()。

文件位置

该文件应该在“PlayerFramework”文件夹下与 “PlayerFramework.h”同级。

PlayerHelper.swift 示例代码

代码内加了完整的注释,需要注意的是整个类需要使用public修饰,对外暴露的方法也需要使用public修饰。

import Foundation/// 播放器辅助类
/// 用于提供外部调用的播放与暂停接口。
public class PlayerHelper {/// 初始化方法public init() {}// MARK: - 对外暴露的接口/// 开始播放/// 调用该方法后会触发内部加载逻辑(示意)public func play() {print("🎵 Start playing...")loadMediaFile()}/// 暂停播放/// 暂停当前的播放任务public func pause() {print("⏸ Pause playback.")}// MARK: - 私有逻辑(不会对外暴露)/// 加载媒体文件,仅供内部调用/// 外部工程无法访问此方法private func loadMediaFile() {print("🔒 Load media from local file system.")}
}

2.3 设置配置信息

接下来我们还需要到“Build Setting”中查看一下配置信息,大多数情况下这些配置都是符合要求的,但是我们在这里还是来介绍一下,以便满足不同的需求。

设置 Defines Module

Build Settings → Packaging → Defines Module
将其设置为YES。
 

  • 表示当前 Framework 会作为一个独立的 Swift Module 存在。
  • 外部项目才能通过 import PlayerFramework 导入你的框架。
  • 如果关闭,则 Swift 编译器无法识别模块名。

 设置 Build Libraries for Distribution

Build Settings → Build Options → Build Libraries for Distribution
将其值设置为:YES。

  • 启用 Module Stability(模块稳定性),可避免因 Swift 版本不同而无法加载。
  • 生成 .swiftinterface 文件,用于暴露框架 API 接口签名(不会泄露实现代码)。
  • 这是 Swift 框架“被安全调用”的关键一步。

确认 Mach-O Type

Build Settings → Linking → Mach-O Type

选择动态库还是静态库。这个根据自己需要来选择,希望简单点的话直接选择静态库“ Static Library”。

  • 表示生成的 Framework 是一个可动态加载的库。
  • 这也是我们常说的 “动态 Framework”,可以被多个 App 引用而不重复加载。
  • 若选择 Static Library,则会在编译时被打包进 App,这种方式适用于 SDK,不适合模块化分发。

2.4 编译生成Framework

配置信息都检查完成之后,我们直接运行项目或者“command+B” 编译项目,关于生成的是真机使用的还是模拟器:

在Xcode的左上角选择目标设备,可以选择“Any iOS Device (arm64)”来编译适用于真机的版本,或者“Any iOS Simulator Device(arm64,x86_64)”。

也可以参考下面的文章进行合并:

https://blog.csdn.net/weixin_39339407/article/details/142988880?fromshare=blogdetail&sharetype=blogdetail&sharerId=142988880&sharerefer=PC&sharesource=weixin_39339407&sharefrom=from_link

编译成功之后之后,在菜单栏选择“Project” -> “Show build Folder in Finder”

就可以看见我们已经生成的Framework:

我们编译和运行的都是debug包,不能在生产环境使用嗷。
生成release环境的Framework可以选择“Archive”,如果有不太明白的可以私信或者留言。

三. Swift生成的Framework内容解析

当我们构建完成后(无论是运行在真机还是模拟器),在 Products 文件夹中会生成一个成品:

3.1 Headers 文件夹

PlayerFramework.framework/Headers/PlayerFramework.h

这个文件就是我们在工程里看到的 Umbrella Header

在 Objective-C 框架中,这个文件非常重要,

因为只有被列入公共头文件(Public Headers)的符号,才能被外部访问。

但在 Swift 框架中情况完全不同: Swift 框架不会依赖 .h 文件

  • 所有对外可见的符号由 public / open 修饰符控制;
  • 即使删除 .h 文件,Swift 框架依然可以被正常导入;
  • .h 文件的存在主要是为了 兼容 Objective-C 调用 Swift 框架 的情况。

所以,如果你纯 Swift 开发,这个文件几乎没用,只是个“占位符”。

3.2 Info.plist

这是 Framework 的元信息文件,包含:

  • 框架的版本号
  • 编译环境信息
  • Bundle Identifier 等

你基本不需要手动修改它。

3.3 Modules 文件夹

这个文件夹是 Swift 框架能被识别为 模块(Module) 的关键。

module.modulemap

这个文件告诉编译器:“这个 Framework 是一个模块,模块名叫 PlayerFramework。”

内容通常如下:

framework module PlayerFramework {umbrella header "PlayerFramework.h"export *module * { export * }
}

这段配置表示:

  • 框架的对外入口是 PlayerFramework.h
  • 模块名为 PlayerFramework
  • 允许 Swift 和 Objective-C 互操作(export *)

即使你没有手动设置,Xcode 会自动生成。

PlayerFramework.swiftmodule

这个文件夹里放的是 Swift 模块描述文件,它包含几种文件类型:

文件

作用

.swiftmodule

Swift 编译器读取的模块定义(二进制格式)

.swiftdoc

Swift 文档元数据(方法签名、注释等)

.swiftinterface

当你启用 “Build Libraries for Distribution = YES” 后生成的 文本描述文件,用于模块稳定性

3.4 PlayerFramework (二进制文件)

这是整个框架的核心部分。它是编译后的 Mach-O 动态库(.dylib 格式),包含你所有 Swift 源码的编译产物。

四. 使用Framework

接下来我们新建一个普通的Swift项目就叫“TestFrameworkDemo”,然后呢将我们刚刚生成的PlayerFramework 导入到项目中。

在ViewController可以直接引用该Framework,然后按住“command”使用鼠标点击“PlayerFramework”进入内部会发现,只有我们设置为public的方法可以被看见,并且只有方法方法名,并不会暴露方法内部的实现:

里面所有使用public修饰的方法,在外面都可以直接被调用。

五. Swift 与 Objective-C 的区别

其实OC与Swift构建Framework会有区别的根本原因在于Swift 与 Objective-C 在框架暴露机制上的本质区别

5.1 Objective-C:通过「头文件」决定暴露范围

在 Objective-C 的世界里,所有的符号暴露都是通过 头文件(.h) 来完成的。

如果你希望外部项目能访问某个类或方法,必须:

  • 把对应的 .h 文件添加到
  • Build Phases → Headers → Public 下;
  • 在 Umbrella Header(例如 PlayerFramework.h)中 #import 进来。
// PlayerManager.h
@interface PlayerManager : NSObject
- (void)play;
@end

若没有将 PlayerManager.h 添加为 Public,

即使你在别的文件中 import 了,也无法被外部工程识别。

所以,在 OC 框架中,“文件是否被暴露”完全取决于你有没有公开头文件。

5.2 Swift:通过「访问控制修饰符」决定暴露范围

Swift 的设计理念是模块化和安全性优先,

因此框架的暴露范围不再依赖外部文件配置,而是完全由 访问控制修饰符 决定:

修饰符

可见范围

说明

private

当前文件内

完全隐藏

fileprivate

当前源文件

类似私有

internal(默认)

当前模块

默认,仅框架内部可见

public

可被其他模块访问

框架对外公开的 API

open

可被访问且可被继承/重写

用于需要被扩展的 API

无需再去设置 “Public Headers”,Swift 编译器会根据修饰符自动生成 .swiftinterface 接口文件,供外部模块识别和调用。

5.3 模块层面的区别

对比项

Objective-C

Swift

暴露机制

头文件(Public Headers)

访问修饰符(public/open)

入口文件

Umbrella Header (.h)

自动生成 modulemap

接口文件

.h 文件

.swiftinterface 文件

源码泄露风险

可能(若暴露实现文件)

无(只生成签名信息)

模块导入方式

#import <Framework/Header.h>

import FrameworkName

六.结语

通过本篇教程,我们完整演示了 Swift 项目生成 Framework 的流程,并重点解析了其与 Objective-C 的区别:

  • Swift 不依赖 Public Headers 来控制暴露范围,而是通过 访问修饰符 决定哪些方法可被外部访问;
  • 编译生成的 .framework 中只包含 二进制和接口签名,源码不会暴露;
  • 对外暴露的 public 方法只是签名,对实现逻辑是不可见的,这让框架更加安全和可维护。

掌握这些原理后,你就可以自信地构建 Swift 框架,安全、规范地对外提供接口,同时保留内部实现的私密性。

http://www.dtcms.com/a/564667.html

相关文章:

  • C++多线程同步与互斥
  • Python Jupyter Notebook 完全指南:从入门到精通
  • 站点查询wordpress 外贸网站
  • CSP集训错题集 第八周 主题:基础图论
  • 基于C语言 HTTP 服务器客户端的实验
  • 如何利用 Jupyter 从浏览器访问远程服务器
  • C语言基础知识点简单案例分享之二——C语言全知识点速查宝典
  • 怎么找网站局域网电脑做网站服务器
  • 一男一女做那个的动漫视频网站网站怎样推广 优帮云
  • hive常用命令
  • AWS + 飞天CMS:高性能内容站的云端搭建方案
  • 800G光模块:驱动AI与云计算高速互联的核心引擎
  • Python每日一练---第三天:删除有序数组中的重复项
  • U-Net 的输入与输出:通用场景与扩散模型场景解析
  • 李宏毅机器学习笔记39
  • 【代码随想录算法训练营——Day57(Day56周日休息)】图论——53.寻宝
  • PPT+配音生成带旁白的PPT演示视频
  • abp vnext cli无法正常使用,卡在 Checking extensions..,cli修改abp版本及.net版本
  • 萤石摄像头使用NAS作为存储
  • 2025江西省职业院校技能大赛(中职组)移动应用与开发竞赛样题
  • 建站公司哪家好在哪里推广比较好
  • 在 iOS 18 的照片应用,如何批量隐藏截屏?
  • OK3568 Android11 实现 App 独占隔离 CPU 核心完整指
  • 湖南网站建设公司 都来磐石网络泰安营销型网站建设公司
  • Oracle 如何计算 AWR 报告中的 Sessions 数量
  • JavaScript 流程控制语句
  • 走向专精:我的NLP特化算子开发之旅
  • 如何写prompt?prompt收集
  • 打工人日报#20251103
  • 技术文章大纲:设备如何“开口说话”?