最近工作中的开发内容涉及到 Framework 的开发和运用,遇到一些问题,也算是解决了。 这里有一些根本的装备,记载一下,还有 简略的 XCFramework 装备运用。干货儿满满,收藏点赞!

Framework 的装备

Build Setting

  • Build Libraries for Distribution – YES
  • Mach-O Type – Static Labriry (可选)

运用 .bundle

  1. 右键点击项目名。
  2. 挑选 New Group
  3. 设置bundle姓名:xxx.bundle
  4. 在这个目录汇中增加文件,能够增加代码用到的资源,途径便是xxx.bundle/xx

Pods 三方库

在 Framework 中运用了的pod依靠,那么在引进Framework 的项目中也要参加相应的依靠,而且版别不能小于Framework 中的三方库版别。

开发 Framework

在 demo 中开发 framework,能够运用 Add Files 参加xcodeproj。

  • General – Frameworks, Librarise, embed content – do not embed framework
  • Build Phases – Target Dependencies 增加 framework
  • Link Binary With Library – 增加 framework

构建

构建对应真机和模拟器的framework的文件,会在Xcode设置的目录下生成。 在这里 Xcode Setting – Loccasions – Derived Data 能够查看目录方位。在目录下的 /<Framework target name>/Build/Products/途径,能够看到对应的文件夹。 真机和模拟器(iphonesimulator),在这个文件夹下边,就能够找到 XXX.framework。直接拖到项目中即可运用。

Target 装备

Xcode 项目引进 Static Labriry 类型 Framework 装备,

引进的项目中的 Target – General – Frameworks and Libraries – Do Not Embed

假如是 dynamic library,则以上设置 需要是 – Embed and Sign

和 Framework 相关的 XCFramework

XCFramework 适用于打包多渠道的状况,其包内会有相关装备,当把生成的 XCFramework 导入到项目中,主动就能依据运转的渠道进行判别构建,方便开发。从而替代以前运用 lipo 合并 framework 架构的状况,也少了一些 target 的 build setting 设置。

至于运转创立 XCFramework,也很简略,运用指令行脚本即可。

下面,就开始一个例子,来看怎样开发一个framework,以及怎么多渠道打包吧。

创立 framework 的 demo

demo 运用的是 Xcode 14.2

顺次挑选:File – New – Project…,挑选 iOS – Framework

在 iOS Swift 开发中 简单地使用 XCFramework

设置 framework 名称为 DemoFramework,然后挑选一个存储方位。

在 iOS Swift 开发中 简单地使用 XCFramework

创立好的 demoFramework 如下图,咱们现已参加一个 HelloworldViewController 文件,是一个展示Helloworld 文字的 UIViewController。

在 iOS Swift 开发中 简单地使用 XCFramework

另外,还把 Build Libraries for Distribution 设置为 YES。这是依据前边的记载,打包 XCFramework 所用到的设置。

创立 调试Framework 的 Demo App

创立新的 App项目的话,大家现已很熟,不再胪陈。

创立好名为 DemoTestFramework 的项目后,右键点击左边目录的 DemoTestFramework Target – Add Files to “DemoTestFramework”,然后挑选 DemoFramework,留意不要挑选 Copy Item If needed

在 iOS Swift 开发中 简单地使用 XCFramework

增加好之后,如下图所示,其中还增加了一些设置。

在 iOS Swift 开发中 简单地使用 XCFramework

  • 图中1区:这是增加后的项目目录。
  • 图中2区:导入framework,然后让主视图操控承继 DemoFramework 中的 HelloworldViewController
  • 图中3区:在 TARGETS – DemoTestFramework – General选项卡 – Framework, Libraries, and Embedded Content 中,增加了咱们引进项目的 demo framework。
  • 图中4区:在 TARGETS – DemoTestFramework – Build Phases – Target Dependencies 中,增加了 demo framework,这里是为了在修正 Framework 内容的一起,也会把 Framework 内容一起 build 一遍。

咱们挑选 14 pro模拟器 ,Run 一下,能够看到,项目现已成功运转,Demo Framework 也成功引进了 demo app。

在 iOS Swift 开发中 简单地使用 XCFramework

现在,咱们把 Demo Framework 中的 Label 内容,改为”Hello, Swift 6.0!”,然后 Run 一下。

在 iOS Swift 开发中 简单地使用 XCFramework

运转成功,显现正确!

这就阐明,关于 Framework 的修正,现已成功被 Demo app 调用。

打包 Demo Framework 为 XCFramework

成功修正之后,就能够打包发布,以供其他项目引进运用。 这里直接上脚本,在脚本中解说吧。

#!/bin/sh
# 假如脚本放进Xcode的run script中运转,能够不设置这个PROJECT_NAME,
# 由于它一起也是 Xcode 项目的全局变量,用于获取项目名。
PROJECT_NAME=DemoFramework
# 咱们framework的姓名是和项目名相同的,假如不相同的的话,能够独自设置。
framework_name=$PROJECT_NAME
# 导出xcframework的途径
output_path=$HOME/${framework_name}_XCFramework
# 模拟器的存档方位
simulator_archive_path=$output_path/simulator.xcarchive
# 真机的存档方位
iOS_device_archive_path=$output_path/iOS.xcarchive
# 删除旧版,然后创立新版
rm -r $output_path
mkdir $output_path
# 打包模拟器
xcodebuild archive \
-scheme $framework_name \
-destination "generic/platform=iOS Simulator" \
-archivePath $simulator_archive_path \
SKIP_INSTALL=NO
# 打包真机
xcodebuild archive \
-scheme $framework_name \
-destination "generic/platform=iOS" \
-archivePath $iOS_device_archive_path \
SKIP_INSTALL=NO
# 创立 xcframework
xcodebuild -create-xcframework \
-framework $simulator_archive_path/Products/Library/Frameworks/$framework_name.framework \
-framework $iOS_device_archive_path/Products/Library/Frameworks/$framework_name.framework \
-output $output_path/$framework_name.xcframework
# 打包完成后,存档就失去效果,只作为中心打包进程运用。
rm -r $simulator_archive_path $iOS_device_archive_path
# 翻开 XCFramework 所在的目录
open $output_path

能够直接将脚本内容放入Xcode的脚本中,注释掉项目名的设置,直接运转含有脚本的 Target 就行。 而我的脚本是以sh文件的办法放在项目根目录中的,假如你也是这样,直接运用指令运转即可,无需修正内容。

$ cd <DemoFramework 的项目途径>
$ sh DemoOutputXCFramework.sh

运转成功,会得到这样的文件结构。

.
└── DemoFramework.xcframework
    ├── Info.plist
    ├── ios-arm64
    └── ios-arm64_x86_64-simulator

这便是创立在用户目录下的 XCFramework 文件内容**。**

导入项目运用

首先删除左边目录中关于 DemoFramework Target 的引证。

然后,直接将生成的 DemoFramework.xcframework 拖入 TARGETS – DemoTestFramework – General选项卡 – Framework, Libraries, and Embedded Content 中,如下图所示。

在 iOS Swift 开发中 简单地使用 XCFramework

挑选模拟器或真机,都Run一下,和预期相同,屏幕显现 “Hello, Swift6.0!”字样。 这样咱们就为项目增加好了 XCFramework,而且模拟器和真机都能够运转。

有pod 依靠的状况

上边的操作,都是基于无三方依靠的状况,假如咱们的 Framework 中,增加了 Pods 依靠的话,状况又不太相同。

咱们先在项目中增加 Pod依靠,在例子中,是参加了 SnapKit 这个布局库,进程省略,说起依靠,其实cocopods的简略操作也是个不错的主题,今后有时间能够总结一下。

由于采用了pods依靠,那么咱们在 xcodebuild 指令中,需要加一条 -workspace $workspace_name, 由于 pod项目运转的是 DemoFramework.xcworkspace, 咱们实践 build的对象是指定的 workspace。脚本如下:

#!/bin/sh
# 假如脚本放进Xcode的run script中运转,能够不设置这个PROJECT_NAME,
# 由于它一起也是 Xcode 项目的全局变量,用于获取项目名。
PROJECT_NAME=DemoFramework
# 咱们framework的姓名是和项目名相同的,假如不相同的的话,能够独自设置。
framework_name=$PROJECT_NAME
# +++ 参加pods今后,指定 build 的 workspace
workspace_name="${PROJECT_NAME}.xcworkspace"
# 导出xcframework的途径
output_path=$HOME/${framework_name}_XCFramework
# 模拟器的存档方位
simulator_archive_path=$output_path/simulator.xcarchive
# 真机的存档方位
iOS_device_archive_path=$output_path/iOS.xcarchive
# 删除旧版,然后创立新版
rm -r $output_path
mkdir $output_path
# +++ 参加pods今后,打包模拟器
xcodebuild archive \
-workspace $workspace_name \
-scheme $framework_name \
-destination "generic/platform=iOS Simulator" \
-archivePath $simulator_archive_path \
SKIP_INSTALL=NO
# +++ 参加pods今后,打包真机
xcodebuild archive \
-workspace $workspace_name \
-scheme $framework_name \
-destination "generic/platform=iOS" \
-archivePath $iOS_device_archive_path \
SKIP_INSTALL=NO
# 创立 xcframework
xcodebuild -create-xcframework \
-framework $simulator_archive_path/Products/Library/Frameworks/$framework_name.framework \
-framework $iOS_device_archive_path/Products/Library/Frameworks/$framework_name.framework \
-output $output_path/$framework_name.xcframework
# 打包完成后,存档就失去效果,只作为中心打包进程运用。
rm -r $simulator_archive_path $iOS_device_archive_path
# 翻开 XCFramework 所在的目录
open $output_path

假如是以脚本文件的办法放在项目根目录下,运转办法和上边没有pods依靠的办法相同。 得到的 XCFramework目录也是相同的。这部分上边已有胪陈。

然后咱们参加项目 DemoFramework,运用真机运转一下,结果如预期。

但是在模拟器运转的时分,我遇到一个错误。

arm64-apple-ios-simulator.private 报错

/Users/youwei/Library/Developer/Xcode/DerivedData/DemoTestFramework-fiviywlmfwujstdvutfebnogtjuh/Build/Products/Debug-iphonesimulator/DemoFramework.framework/Modules/DemoFramework.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface:6:8
Could not find module 'SnapKit' for target 'arm64-apple-ios-simulator'; 
found: x86_64-apple-ios-simulator, at: /Users/youwei/Library/Developer/Xcode/DerivedData/DemoTestFramework-fiviywlmfwujstdvutfebnogtjuh/Build/Products/Debug-iphonesimulator/SnapKit/SnapKit.framework/Modules/SnapKit.swiftmodule

解决的办法,便是在项目中,关于模拟器的 build setting,扫除 arm64架构即可。

在 iOS Swift 开发中 简单地使用 XCFramework

在项目的 Build Settings – Excluded Architectures – Any iOS Simulator SDK – arm64

这是由于创立 XCFramework 时参加了arm64架构,本身这个应该是归于真机的。

# youwei @ 192 in ~/DemoFramework_XCFramework/DemoFramework.xcframework [17:45:05] C:1
$ lipo -info ios-arm64_x86_64-simulator/DemoFramework.framework/DemoFramework
Architectures in the fat file: ios-arm64_x86_64-simulator/DemoFramework.framework/DemoFra

模拟器 run 一下,好的,现已成功了。

总结

XCFramework 是苹果出的新的二进制打包办法,感觉能够替代以前Framework打包合并渠道架构的办法,能够一起支撑多个渠道,乃至还有 watch OS和 MacOS,而且打包进程简略,在日常工作中,掌握其运用还是有必要的。

最后,假如大家喜爱这篇文章的话,记得收藏,点赞,转发!