Appearance
Swift 入门(22):模块导入与导出
如何导入系统框架、第三方库,以及如何设计自己的模块对外接口。
什么是模块(Module)
在 Swift 中,模块是代码分发的基本单位。每个模块都有自己的命名空间,可以包含类、结构体、协议、函数等。
常见的模块类型:
- 系统框架:
Foundation、UIKit、SwiftUI等 - 第三方库:通过 CocoaPods、Swift Package Manager 安装的库
- 自定义模块:你自己创建的 Swift Package 或 Framework
import 语法详解
1. 基础导入语法
swift
// 导入整个模块
import Foundation
import UIKit
import AuthenticationServices
// 导入后就可以使用模块中的公开类型
let date = Date() // Foundation.Date
let label = UILabel() // UIKit.UILabel2. 选择性导入
swift
// 只导入模块中的特定类型
import class UIKit.UIViewController
import struct Foundation.URL
import enum Foundation.ComparisonResult
// 导入特定函数
import func Darwin.sqrt3. 重命名导入
swift
// 避免命名冲突
import UIKit
import class MyFramework.UIView as MyUIView
// 使用时区分
let systemView = UIView() // UIKit.UIView
let customView = MyUIView() // MyFramework.UIView4. 测试专用导入
swift
// 仅在测试环境导入
#if DEBUG
import TestingFramework
#endif
@testable import MyApp // 可以访问 internal 级别的内容你提到的三个框架详解
Foundation
swift
import Foundation
// Foundation 提供基础数据类型和系统服务
let string = "Hello"
let date = Date()
let url = URL(string: "https://example.com")
let data = Data()
let userDefaults = UserDefaults.standard常用场景:字符串处理、日期时间、网络请求、数据存储、JSON 解析
UIKit
swift
import UIKit
// UIKit 提供 iOS 用户界面组件
let viewController = UIViewController()
let label = UILabel()
let button = UIButton(type: .system)
let imageView = UIImageView()常用场景:构建传统 iOS 界面、处理触摸事件、导航控制、动画
AuthenticationServices
swift
import AuthenticationServices
// 提供生物识别、Passkeys 等认证服务
let context = ASAuthorizationController()
let provider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: "example.com")常用场景:Face ID/Touch ID 认证、Passkeys 登录、Safari 密码自动填充
模块的访问控制
访问级别从高到低
swift
// 1. open - 最开放,可被其他模块继承和重写
open class BaseViewController: UIViewController {
open func setup() { }
}
// 2. public - 可被其他模块访问,但不能继承
public class APIClient {
public func request() { }
}
// 3. internal - 模块内部可访问(默认级别)
internal class NetworkManager {
func sendRequest() { }
}
// 4. fileprivate - 同一文件内可访问
fileprivate class FileHelper {
func process() { }
}
// 5. private - 最严格,只有当前作用域可访问
private class Secret {
private func encrypt() { }
}如何设计可导出的模块
1. 创建 Swift Package
bash
# 创建新的 Swift Package
mkdir MyAwesomeKit
cd MyAwesomeKit
swift package init --type library生成的 Package.swift:
swift
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyAwesomeKit",
products: [
.library(
name: "MyAwesomeKit",
targets: ["MyAwesomeKit"]),
],
targets: [
.target(
name: "MyAwesomeKit",
dependencies: []),
.testTarget(
name: "MyAwesomeKitTests",
dependencies: ["MyAwesomeKit"]),
]
)2. 设计公开 API
swift
// Sources/MyAwesomeKit/MyAwesomeKit.swift
import Foundation
// 对外暴露的主要接口
public class NetworkClient {
public init() {}
public func get(url: String) async throws -> Data {
// 实现网络请求
return Data()
}
}
// 对外暴露的协议
public protocol DataProcessor {
func process(_ data: Data) -> String
}
// 内部实现,不对外暴露
internal class InternalHelper {
static func format(_ data: Data) -> String {
return String(data: data, encoding: .utf8) ?? ""
}
}
// 私有实现
private extension NetworkClient {
func buildRequest(url: String) -> URLRequest? {
guard let url = URL(string: url) else { return nil }
return URLRequest(url: url)
}
}3. 使用你的模块
swift
// 在其他项目中使用
import MyAwesomeKit
class ViewController: UIViewController {
let client = NetworkClient()
override func viewDidLoad() {
super.viewDidLoad()
Task {
do {
let data = try await client.get(url: "https://api.example.com")
print("获取到数据:\(data.count) bytes")
} catch {
print("请求失败:\(error)")
}
}
}
}实际开发中的最佳实践
1. 按功能模块化导入
swift
// 好的做法:按需导入
import Foundation // 基础类型
import UIKit // UI 组件
import AuthenticationServices // 认证相关
class LoginViewController: UIViewController {
// 使用各个模块的功能
}2. 避免循环依赖
swift
// ❌ 避免这样的循环依赖
// ModuleA 导入 ModuleB
// ModuleB 导入 ModuleA
// ✅ 正确做法:提取公共协议到独立模块
// ModuleA 和 ModuleB 都依赖 CommonProtocols3. 合理设计访问级别
swift
public class UserManager {
// 对外接口
public func login(username: String, password: String) async -> Bool {
return await performLogin(username, password)
}
// 内部实现
private func performLogin(_ username: String, _ password: String) async -> Bool {
// 具体登录逻辑
return true
}
// 内部状态
private var isLoggedIn = false
}常见问题与解决方案
问题 1:模块找不到
swift
// 错误信息:No such module 'SomeFramework'
// 解决方案:
// 1. 检查 import 语句拼写
// 2. 确认已在 Package.swift 或 Podfile 中添加依赖
// 3. 清理构建缓存:Product → Clean Build Folder问题 2:访问级别错误
swift
// 错误信息:'SomeClass' is inaccessible due to 'internal' protection level
// 解决方案:确保要访问的类型标记为 public 或 open
// 模块内部
public class SomeClass { // 添加 public 关键字
public init() {} // 构造函数也需要 public
}问题 3:命名冲突
swift
// 两个模块都有同名类型
import ModuleA
import ModuleB
// 使用完整名称区分
let a = ModuleA.SomeClass()
let b = ModuleB.SomeClass()
// 或者使用重命名导入
import struct ModuleB.SomeClass as ModuleBClass小结
这一篇我们学习了 Swift 的模块系统:
- import 语法:基础导入、选择性导入、重命名导入
- 系统框架:Foundation、UIKit、AuthenticationServices 的用途
- 访问控制:open、public、internal、fileprivate、private 五个级别
- 模块设计:如何创建可复用的 Swift Package
- 最佳实践:避免循环依赖、合理设计 API、处理常见问题
下一篇我们将学习 Swift 的包管理器和依赖管理,让你能够更好地使用和分发 Swift 模块。