本文的实现方式来自这篇文章,我对其内容进行总结和补充。
在上一篇文章中介绍了什么是宏以及怎么创建宏,本文将介绍如何使用 CocoaPods 分发 Swift 宏。
将宏编译成二进制文件
进入到宏工程的目录下,执行 build 命令:
bash
swift build -c release
⚠️注意:Package 中的 platforms 必须包含 macOS
平台,否则编译会报错。
等待编译结束后,可以在 .build/release
中找到 Macros
结尾的二进制文件,例如:MyMacroMacros
。
在宏工程的根目录下创建 macros/
文件夹,并将二进制文件复制进来。
修改 Podspec 文件
需要修改这个 Podspec 文件,告诉 CocoaPods 在哪里可以找到宏的二进制文件,以及如何处理它:
ruby
Pod::Spec.new do |s|
s.name = 'MyMacroExample'
s.version = '0.1.0'
s.summary = 'A proof of concept macro to show they can work with cocoapods.'
s.description = <<-DESC
A proof of concept macro to show they can work with cocoapods.
DESC
s.homepage = '<homepage>'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { '<your_name>' => '<your_email>' }
s.source = { :git => '<repository_where_the_spec_lives>', :tag => s.version.to_s }
s.ios.deployment_target = '13.0'
# 1
s.source_files = ['Sources/MyMacro/**/*']
s.swift_version = "5.9"
# 2
s.preserve_paths = ["macros/MyMacroMacros"]
# 3
s.pod_target_xcconfig = {
'OTHER_SWIFT_FLAGS' => '-load-plugin-executable ${PODS_ROOT}/MyMacroExample/macros/MyMacroMacros#MyMacroMacros'
}
# 4
s.user_target_xcconfig = {
'OTHER_SWIFT_FLAGS' => '-load-plugin-executable ${PODS_ROOT}/MyMacroExample/macros/MyMacroMacros#MyMacroMacros'
}
end
接下来我们一步步地解释 Podspec 文件中重要的部分:
- 宏的定义文件
- 宏是二进制文件不是源文件,因此需要告诉 CocoaPods 将源文件复制到主工程时保留它,以便可以链接到它。
- 对当前 pod 工程的
OTHER_SWIFT_FLAGS
配置项增加-load-plugin-executable
配置和二进制文件的路径。 - 步骤 3 不足以使宏可在主工程中使用。当您尝试在主工程中使用宏时 Xcode 会报错,找不到宏的实现。若要解决此问题,需要修改
user_target_xcconfig
将相同的配置添加到主工程。
导入和使用宏
您可以在 GitHub 上查看本文的 Demo。
发布 CocoaPod 后,只需要在主工程引入这个 pod 即可使用。
ruby
target 'TestPodMarco' do
pod 'MyMacroExample'
end
运行 pod install
之后,您应该可以在主工程使用宏了,示例如下:
swift
import MyMacroExample
@CaseDetection
enum Animal {
case cat
case dog
}
let animal = Animal.cat
if animal.isCat {
// Do some things
}
到目前为止主工程已经可以顺利使用宏了,但是当您尝试在其他 pod 组件中使用宏时 Xcode 又会报错。解决方式是通过 pod install hook 给所有 pod 工程的 OTHER_SWIFT_FLAGS
配置项加上对应配置,示例如下:
ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# 为了让组件也可以使用宏,需要加入以下代码,如果有新的宏需要继续添加
config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -load-plugin-executable ${PODS_ROOT}/MyMacroExample/macros/MyMacroMacros#MyMacroMacros'
end
end
end
总结
在宏刚发布的时候就写了一些能提高生产力的宏,但是碍于 SPM 的依赖方式无法在项目中使用,现在宏可以通过 Pod 进行分发,相信这对大家能产生非常大的助力。
当您实际操作一遍会发现宏的二进制文件大小近 20 MB,如果有多个组件都做了宏那大小就是 20 * N。不过请放心,宏是在编译阶段进行的处理,这个二进制文件并不会打进 ipa 里面,对包体积没有影响。
参考资料 & 资源