如何手动将 .xcframework 添加到 Flutter iOS 插件?
How to manually add a .xcframework to a Flutter iOS Plugin?
我正在尝试创建一个 Flutter 插件以使用本机库。
我尝试使用的这个库存储在私有存储库中,可以与 Swift Dependency Manager 一起使用。
这让我很头疼,因为我无法在我的插件中添加私有存储库依赖项(我无法在 .podspec 文件中找到执行此操作的方法),所以我所做的是:
- 我已经使用 Swift 包管理器
将插件添加到示例项目中
- 手动将
MyDependency.xcframework
文件夹复制到 MyPlugin/ios
文件夹
- 在 podspec 文件中引用它,如下所示:
s.preserve_paths = 'MyDependency.xcframework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework MyDependency' }
s.vendored_frameworks = 'MyDependency.xcframework'
这样我就可以在插件的源代码中使用 MyDependency。
我目前的问题是:这只能在模拟器中工作。
在执行此操作之前,该项目 运行ning 在实际设备中没有任何问题。
这是我每次尝试在真实设备中 运行 时收到的错误消息:
此外,我已经使用直接来自 Swift 依赖管理器的依赖项进行了测试,并且工作正常。我认为问题在于我将框架添加到我的插件的方式。
经过一些研究,我发现 some links 让我对真正的问题有了一个想法...
为了解决这个问题,我在主项目的构建过程中添加了一个简单的脚本。
此脚本将代码签名添加到内部 .framework
文件。
cd "${CODESIGNING_FOLDER_PATH}/Frameworks/"
# flatten nested frameworks by copying to APP.app/Frameworks
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Moving embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
cp -R "${framework}/Frameworks/" .
rm -rf "${framework}/Frameworks"
fi
fi
done
# remove any leftover nested frameworks (i.e. 'PackageName_359AFEED79E48935_PackageProduct.framework')
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Removing embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
rm -rf "${framework}/Frameworks"
fi
fi
done
# codesign for Debugging on device
if [ "${CONFIGURATION}" == "Debug" ] & [ "${SDKROOT}" != *Simulator* ] ; then
echo "Code signing frameworks..."
find "${CODESIGNING_FOLDER_PATH}/Frameworks" -maxdepth 1 -name '*.framework' -print0 | while read -d $'[=10=]' framework
do
# only sign frameworks without a signature
if ! codesign -v "${framework}"; then
codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --preserve-metadata=identifier,entitlements --timestamp=none "${framework}"
echo "Added missing signature to '${framework}'"
fi
done
fi
我通过将以下行添加到 xxx.podspec
:
使我的工作正常
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
注意 s.preserve_paths
末尾的 /**/*
这是完整的 xxx.podspec
文件:
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint xxx.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'xxx'
s.version = '1.0.0'
s.summary = 'xxx'
s.description = <<-DESC
xxx is a flutter plugin
DESC
s.homepage = 'https://example.com'
s.license = { :file => '../LICENSE', :type => 'BSD' }
s.author = { 'xxx' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '10.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
end
确保将 xxxxxx.xcframework
目录复制到 .../xxx/ios/xxxxxx.xcframework
(您的插件 xxx.podspec
所在的位置)
将 xxxxxx.xcframework
添加到 Pods
方案以便能够导入它
当运行 flutter命令创建插件时Frameworks
目录应该在Pods
方案下面
flutter create --org com.xxx --template=plugin --platforms=android,ios -a java -i swift xxx
来源:Developing packages & plugins
(没有则添加)
- 导航到
Pods
方案并右键单击 Frameworks
- 点击
Add Files to "Pods"...
- 导航到
xxxxxx.xcframework
所在的 ios
目录的根目录
- 取消选中
Copy items if needed
- Select
Create folder references
- 勾选
Pods-Runner
- 检查你的插件,即。
xxx
- 点击
Add
将 xxxxxx.xcframework
嵌入到您的项目中
(这应该允许您 run/publish 到真实设备)
- 点击
Pods
方案
- 在
TARGETS
selectPods-Runner
- 单击
General
选项卡
- 确保
xxxxx.xcframework
位于 Frameworks and Libraries
下方(如果没有,请单击 + 添加它)
- 将
Embed
更改为Embed & Sign
- 点击您的插件,即。
xxx
- 确保
xxxxx.xcframework
位于 Frameworks and Libraries
下方
- 将
Embed
更改为Embed & Sign
- 同样,对于低于
Pods
方案的两个目标,接下来的步骤应该已经没问题,但只需检查一下
- 点击
Build Phases
- 点击
Link Binary With Libraries
- 确保
xxxxx.xcframework
存在,如果不存在,请单击 + 添加它,并将 Status
设置为 Required
现在您应该可以导入框架并在您的代码中引用它,并且应该也可以完美发布。
希望这对您有所帮助,祝您好运。我希望这不会很快再次改变
十指相扣
我正在尝试创建一个 Flutter 插件以使用本机库。 我尝试使用的这个库存储在私有存储库中,可以与 Swift Dependency Manager 一起使用。
这让我很头疼,因为我无法在我的插件中添加私有存储库依赖项(我无法在 .podspec 文件中找到执行此操作的方法),所以我所做的是:
- 我已经使用 Swift 包管理器 将插件添加到示例项目中
- 手动将
MyDependency.xcframework
文件夹复制到MyPlugin/ios
文件夹 - 在 podspec 文件中引用它,如下所示:
s.preserve_paths = 'MyDependency.xcframework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework MyDependency' }
s.vendored_frameworks = 'MyDependency.xcframework'
这样我就可以在插件的源代码中使用 MyDependency。
我目前的问题是:这只能在模拟器中工作。
在执行此操作之前,该项目 运行ning 在实际设备中没有任何问题。
这是我每次尝试在真实设备中 运行 时收到的错误消息:
此外,我已经使用直接来自 Swift 依赖管理器的依赖项进行了测试,并且工作正常。我认为问题在于我将框架添加到我的插件的方式。
经过一些研究,我发现 some links 让我对真正的问题有了一个想法...
为了解决这个问题,我在主项目的构建过程中添加了一个简单的脚本。
此脚本将代码签名添加到内部 .framework
文件。
cd "${CODESIGNING_FOLDER_PATH}/Frameworks/"
# flatten nested frameworks by copying to APP.app/Frameworks
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Moving embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
cp -R "${framework}/Frameworks/" .
rm -rf "${framework}/Frameworks"
fi
fi
done
# remove any leftover nested frameworks (i.e. 'PackageName_359AFEED79E48935_PackageProduct.framework')
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Removing embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
rm -rf "${framework}/Frameworks"
fi
fi
done
# codesign for Debugging on device
if [ "${CONFIGURATION}" == "Debug" ] & [ "${SDKROOT}" != *Simulator* ] ; then
echo "Code signing frameworks..."
find "${CODESIGNING_FOLDER_PATH}/Frameworks" -maxdepth 1 -name '*.framework' -print0 | while read -d $'[=10=]' framework
do
# only sign frameworks without a signature
if ! codesign -v "${framework}"; then
codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --preserve-metadata=identifier,entitlements --timestamp=none "${framework}"
echo "Added missing signature to '${framework}'"
fi
done
fi
我通过将以下行添加到 xxx.podspec
:
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
注意 s.preserve_paths
/**/*
这是完整的 xxx.podspec
文件:
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint xxx.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'xxx'
s.version = '1.0.0'
s.summary = 'xxx'
s.description = <<-DESC
xxx is a flutter plugin
DESC
s.homepage = 'https://example.com'
s.license = { :file => '../LICENSE', :type => 'BSD' }
s.author = { 'xxx' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '10.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
end
确保将 xxxxxx.xcframework
目录复制到 .../xxx/ios/xxxxxx.xcframework
(您的插件 xxx.podspec
所在的位置)
将 xxxxxx.xcframework
添加到 Pods
方案以便能够导入它
当运行 flutter命令创建插件时Frameworks
目录应该在Pods
方案下面
flutter create --org com.xxx --template=plugin --platforms=android,ios -a java -i swift xxx
来源:Developing packages & plugins
(没有则添加)
- 导航到
Pods
方案并右键单击Frameworks
- 点击
Add Files to "Pods"...
- 导航到
xxxxxx.xcframework
所在的ios
目录的根目录 - 取消选中
Copy items if needed
- Select
Create folder references
- 勾选
Pods-Runner
- 检查你的插件,即。
xxx
- 点击
Add
将 xxxxxx.xcframework
嵌入到您的项目中
(这应该允许您 run/publish 到真实设备)
- 点击
Pods
方案 - 在
TARGETS
selectPods-Runner
- 单击
General
选项卡 - 确保
xxxxx.xcframework
位于Frameworks and Libraries
下方(如果没有,请单击 + 添加它) - 将
Embed
更改为Embed & Sign
- 点击您的插件,即。
xxx
- 确保
xxxxx.xcframework
位于Frameworks and Libraries
下方
- 将
Embed
更改为Embed & Sign
- 同样,对于低于
Pods
方案的两个目标,接下来的步骤应该已经没问题,但只需检查一下 - 点击
Build Phases
- 点击
Link Binary With Libraries
- 确保
xxxxx.xcframework
存在,如果不存在,请单击 + 添加它,并将Status
设置为Required
现在您应该可以导入框架并在您的代码中引用它,并且应该也可以完美发布。
希望这对您有所帮助,祝您好运。我希望这不会很快再次改变
十指相扣