如何使用 CocoaPods 分发 Swift 宏

本文的实现方式来自这篇文章,我对其内容进行总结和补充。

上一篇文章中介绍了什么是宏以及怎么创建宏,本文将介绍如何使用 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 文件中重要的部分:

  1. 宏的定义文件
  2. 宏是二进制文件不是源文件,因此需要告诉 CocoaPods 将源文件复制到主工程时保留它,以便可以链接到它。
  3. 对当前 pod 工程的 OTHER_SWIFT_FLAGS 配置项增加 -load-plugin-executable 配置和二进制文件的路径。
  4. 步骤 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 里面,对包体积没有影响。


参考资料 & 资源

相关推荐
TT_Close17 小时前
【Flutter×鸿蒙】FVM 不认鸿蒙 SDK?4步手动塞进去
flutter·swift·harmonyos
张江17 小时前
Swift Concurrency学习
swift
东坡肘子3 天前
OpenClaw 不错,但我好像没有那么需要 -- 肘子的 Swift 周报 #125
人工智能·swiftui·swift
Swift社区8 天前
LeetCode 391 完美矩形 - Swift 题解
算法·leetcode·swift
升讯威在线客服系统9 天前
从 GC 抖动到稳定低延迟:在升讯威客服系统中实践 Span 与 Memory 的高性能优化
java·javascript·python·算法·性能优化·php·swift
Swift社区9 天前
LeetCode 390 消除游戏 - Swift 题解
leetcode·游戏·swift
东坡肘子10 天前
春晚、机器人、AI 与 LLM -- 肘子的 Swift 周报 #124
人工智能·swiftui·swift
BatmanWayne13 天前
swift-微调补充
人工智能·swift
疯笔码良17 天前
【swiftUI】实现自定义的底部TabBar组件
ios·swiftui·swift
东坡肘子18 天前
祝大家马年新春快乐! -- 肘子的 Swift 周报 #123
人工智能·swiftui·swift