如何使用 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 里面,对包体积没有影响。


参考资料 & 资源

相关推荐
影寂ldy9 小时前
WinForm PictureBox控件 + ImageList组件 完整笔记
开发语言·笔记·swift
Deepzz1 天前
macOS 上调教第三方鼠标的一些经验:从滚动顺滑到输入法自动切换
macos·swift·鼠标
东坡肘子1 天前
WWDC 26:AI 帮你看完了,然后呢?-- 肘子的 Swift 周报 #140
人工智能·swiftui·swift
大熊猫侯佩2 天前
SwiftData 迁移深度指南:从入门到“填坑”(下集)
数据库·swift·编程语言
大熊猫侯佩2 天前
SwiftData 迁移深度指南:从入门到“填坑”(上集)
数据库·swift·编程语言
多彩电脑3 天前
SwiftUI的导航界面的嵌套问题
开发语言·swift·设计语言
wjm0410063 天前
ios内存管理
ios·objective-c·swift·客户端开发
大熊猫侯佩3 天前
Swift 6.4 的 Ref / MutableRef 大揭秘:给值类型开一扇“安全的小窗”
ios·swift·编程语言
大熊猫侯佩4 天前
WWDC26 SwiftUI 进化之路:砸碎黑盒,彻底迎来开发自由!
ios·swiftui·swift
游戏开发爱好者84 天前
iPhone真机调试有哪些方法?一次定位推送权限问题时整理出来的几种方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程