如何将一个带有依赖(源码 + 二进制)的 Cocoapods pod 打包为 xcframework? —— Ficow 实战总结

| iOS , Xcode , 实用工具 , macOS , CLI(命令行)

想第一时间获取对于自己有帮助的新内容? 欢迎关注 Ficow 的公众号:
学良学不停-compact.png

 

内容概览

  • 前言
  • 将提供了源码的 pod 打包为 xcframework
  • 拷贝提供了 xcframework 文件的 pod
  • 将使用了前两个 pod 的 pod 打包为 xcframework
  • 将三个 xcframework 全部引入消费端项目
  • 总结

 

前言

 

虽然 SPM(Swift Package Manager) 很香,但是你可能依然要维护使用了 Cocoapods 的旧项目,而且是同时使用了提供源码和提供二进制的 pod。

你说什么?居然还要基于这些 pod 构建出一个依赖库,然后把这些依赖库提供给其他多个主项目用???

这个依赖的关系图谱,大概是这样的:

没问题,来和 Ficow 一起看看这题要怎么解~

请注意,本文中涉及到的依赖库仅作为参考示例。

示例项目的仓库地址:PackPodAsXCFrameworkDemo

 

将提供了源码的 pod 打包为 xcframework

 

首先,我们需要把提供了源码的 pod(SnapKit)打包为 xcframework。

 

定义 pod 的 podspec 文件

具体内容,请参考: SnapKit.podspec

这一步中,最重要的就是启用 BUILD_LIBRARY_FOR_DISTRIBUTION 以保证二进制接口 ABI 保持稳定:

 

通过自定义的 podspec 文件引入依赖库

在产出 pod (FicowPod) 的项目 Podfile 中,通过自定义的 podspec 文件引入该依赖库:

 

通过命令行脚本打包依赖库

通过命令行脚本来执行 xcframework 打包命令,方便 CI/CD 调用:

#!/bin/bash

WORKSPACE_NAME="PackPodAsXCFrameworkDemo.xcworkspace"

# 清理 build 目录
rm -rf build

# 拉取 Cocoapods 依赖
pod install

# 如果 pod install 失败了,不继续执行
if [ $? -ne 0 ]; then
    echo "pod install failed. Exiting..."
    exit 1
fi

# 需要构建多个xcframework,定义此方法以复用
build_xcframework() {
    # Build for iOS Device
    xcodebuild archive \
      -workspace $WORKSPACE_NAME \
      -scheme $1 \
      -destination "generic/platform=iOS Simulator" \
      -configuration Release only_active_arch=no \
      -sdk iphoneos \
      -archivePath build/ios_devices.xcarchive \
      SKIP_INSTALL=NO \
      BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \
      OTHER_SWIFT_FLAGS="-Xfrontend -module-interface-preserve-types-as-written"

    if [ $? -ne 0 ]; then
        echo "Build $1 for iOS Device failed. Exiting..."
        exit 1
    fi

    # Build for iOS Simulator
    xcodebuild archive \
      -workspace $WORKSPACE_NAME \
      -scheme $1 \
      -destination "generic/platform=iOS" \
      -configuration Release only_active_arch=no \
      -sdk iphonesimulator \
      -archivePath build/ios_simulator.xcarchive \
      SKIP_INSTALL=NO \
      BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \
      OTHER_SWIFT_FLAGS="-Xfrontend -module-interface-preserve-types-as-written"


    if [ $? -ne 0 ]; then
        echo "Build $1 for iOS Simulator failed. Exiting..."
        exit 1
    fi

    # Create XCFramework
    xcodebuild -create-xcframework \
      -framework build/ios_devices.xcarchive/Products/Library/Frameworks/$1.framework \
      -framework build/ios_simulator.xcarchive/Products/Library/Frameworks/$1.framework \
      -output build/$1.xcframework

    # Remove archives
    rm -rf build/ios_devices.xcarchive
    rm -rf build/ios_simulator.xcarchive

    if [ $? -ne 0 ]; then
        echo "Create $1 XCFramework failed. Exiting..."
        exit 1
    fi
}

build_xcframework SnapKit

请注意,以上代码片段只包含了当前步骤所需的命令。

这是更全的脚本命令内容:build_xcframework.sh

在项目根目录执行该脚本之前,你可能还需要运行 chmod +x build_xcframework.sh 来为该脚本文件添加执行权限。

这一步操作都成功之后,项目根目录会出现一个 build 文件夹,里面会有生成的 SnapKit.xcframework

请注意,这里生成的二进制 framework 文件可以同时支持模拟器和真机。

 

拷贝提供了 xcframework 文件的 pod

 

由于 Cocoapods 中的 pod 既可以提供源码给开发者,也可以直接提供打包好的二进制文件。

所以,我们在打包最终产出的 xcframework 时,也需要考虑如何处理直接提供二进制的 pod。

但是,其实这种情况很容易处理,请直接看下面的脚本命令注释吧~

# 拉取依赖
pod install

# 直接复制 xcframework 目录到最终产出目录
cp -R Pods/GenesysCloudMessengerTransport/MessengerTransport.xcframework build/MessengerTransport.xcframework

产出效果如图所示:

 

将使用了前两个 pod 的 pod 打包为 xcframework

 

了解代码中的依赖关系

最终要产出的是 FicowPod.xcframework,它依赖的两个 pod 对应的 xcframework 都已经就绪。

只要我们最终导出的 FicowPod.xcframework 在集成到消费端项目中时,能正常打印 Hello from FicowPod!,那么我们的终极目标就达成了。

打包 FicowPod

这一步,其实只需要调用之前定义的 build_xcframework 脚本方法即可:

build_xcframework FicowPod

读者朋友,是不是很 easy 呢?😄

同样的,产出效果如图所示:

 

将三个 xcframework 全部引入消费端项目

 

虽然非常不舍,但是故事真的就快接近尾声了~ 🤣

 

这是消费端项目:XCFrameworkConsumerDemo

拖拖拽拽,3个产出物 xcframework 就这么被集成进去了。然后,直接调用一下 FicowPod 提供的 hello() 方法:

最后,运行该项目,你就会看到两行非常朴实(寡淡无味)的文本:

Yeah, that’s it~

 

如果你对产出的 xcframework 还有更多的定制需求,可以查看文末提供的 Cocoapods 和 Apple 官方文档以查询更多配置项。

 

总结

 

很多开发人员一听到 SDK 就很头痛,因为集成 SDK 通常会遇到各种奇奇怪怪的问题。

为什么会是奇奇怪怪的问题呢?

因为,这不是自己的舒适圈,这不是平时那种简单纯粹的打代码的玩法。

越是多接触这些难题,你就越发地觉得自己需要学习的东西实在太多,只是打代码是远远不够的呢。

除了要了解开发语言、数据库等,我们还要更加深入地学习依赖管理、操作系统、计算机硬件架构等等内容。

 

朋友,你有没有觉得越听越兴奋呢?恭喜你,你一定是一位爱学习的技术大咖~

 

参考内容:

  1. Bash Shell Scripting:
  2. CocoaPods Documentation:
  3. Xcode and XCFrameworks:
  4. Command Line Interface (CLI) in Bash:
  5. macOS Terminal Usage:

 

觉得不错?点个赞呗~

本文链接:如何将一个带有依赖(源码 + 二进制)的 Cocoapods pod 打包为 xcframework? —— Ficow 实战总结

转载声明:本站文章如无特别说明,皆为原创。转载请注明:Ficow Shen's Blog

评论区(期待你的留言)