本系列之前的文章:
本系列文章对应的示例工程源码库地址:github.com/pmtao/XCFra…
本文讨论制作 Swift 动态库类型的 XCFramework.
创建 Framework 工程
- 首先创建一个空的 Swift Framework 工程,在工程中添加一个 Swift 文件:
- 添加一个简单的测试类:
import Foundation
@objc public class SwiftFrameworkExample: NSObject {
@objc public var title = "Swift Framework is working."
}
生成 XCFramework 文件
- 制作动态库类型的 XCFramework 需要两个步骤:先创建 Archive,再生成 XCFramework 文件。先来生成 Archive 文件,为了调试和发布的需要,我们要生成两个 Archive 文件,分别针对模拟器和真机,在终端中进入 Framework 工程目录,执行以下脚本:
xcodebuild archive \
-scheme SwiftFrameworkExample \
-destination "generic/platform=iOS" \
-archivePath "../SwiftFrameworkExample" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
以上脚本中,scheme 对应工程的 scheme 名称,destination 为构建目标平台,archivePath 表示生成的 archive 路径,生成结果为上一级目录的 SwiftFrameworkExample.xcarchive
文件,最后两项为构建和发布必须的参数。
- 生成模拟器版本对应的脚本如下:
xcodebuild archive \
-scheme SwiftFrameworkExample \
-destination "generic/platform=iOS Simulator" \
-archivePath "../SwiftFrameworkExample-simulator" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
- 执行以下脚本生成 XCFramework 文件:
xcodebuild -create-xcframework \
-framework ./SwiftFrameworkExample.xcarchive/Products/Library/Frameworks/SwiftFrameworkExample.framework \
-framework ./SwiftFrameworkExample-simulator.xcarchive/Products/Library/Frameworks/SwiftFrameworkExample.framework \
-output ./SwiftFrameworkExample.xcframework
- 最终生成的 XCFramework 内部结构如下:
在 Swift 工程中使用 XCFramework
- 使用非常简单,将 XCFramework 文件拖拽至工程设置页的 TARGETS → General → Frameworks 里,在代码里直接调用即可:
import UIKit
import SwiftFrameworkExample
class ViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let title = SwiftFrameworkExample().title
titleLabel.text = title
}
}
- 对比之下,静态库还需要额外再导入
.swiftmodule
文件,因为 Framework 类型的 XCFramework 内部已经包含了.swiftmodule
文件。
在 Objective-C 工程中使用 XCFramework
- 使用方法也类似,将 XCFramework 文件添加到工程中,并设置 Framework 链接(TARGETS → General → Frameworks ),在代码中直接 import 即可,注意此处是以 module 的方式引入:
@import SwiftFrameworkExample;
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *title = [SwiftFrameworkExample new].title;
self.titleLabel.text = title;
}
@end
总结
动态库类型的 XCFramework 使用起来比静态库类型的 XCFramework 相对简单些,不需要引入头文件或 swiftmodule
文件,通过 module import 的方式引用即可。