如何手动将 .xcframework 添加到 Flutter iOS 插件?
Posted
技术标签:
【中文标题】如何手动将 .xcframework 添加到 Flutter iOS 插件?【英文标题】:How to manually add a .xcframework to a Flutter iOS Plugin? 【发布时间】:2021-11-11 19:27:22 【问题描述】:我正在尝试创建一个 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。
我目前的问题是:这只适用于模拟器。
在此之前,该项目在真实设备上运行没有任何问题。
这是我每次尝试在真实设备上运行时收到的错误消息:
另外,我已经直接从 Swift Dependency Manager 使用依赖项进行了测试,并且工作正常。我认为问题在于我将框架添加到插件的方式。
【问题讨论】:
你在没有.xcframework
的iOS物理设备上成功构建应用了吗?此外,您不需要添加所有 3 个步骤(cocoapods、SPM 和 xcframework)。只需将.xcframework
拖入您的项目即可。
是的,没有 .xcframework 它工作正常。我不想将 .xcframework 直接拖到我的项目中。我需要创建一个可以在我们这里拥有的其他项目中使用的插件。另外,我(认为)没有直接访问 .xcframework 的权限。我执行这 3 个步骤只是为了让 SPM 下载的文件。
那么,您希望该封闭源代码的分发策略是什么?我不明白如果 SPM 是封闭源代码,您如何使用它。
第一个屏幕截图发生在您没有正确设置项目/设备时。您的设备需要自动添加到您的配置文件中。我认为您拥有 Apple Developer Program 会员资格并在签名和能力下选择了正确的团队?
第二个屏幕截图(在您的示例项目 Runner 中显示 SPM)只是您的库,它可能/可能没有 .xcframework
。此外,当用户将您的插件添加到他们的项目中时,您的插件会通过 cocoapods 而不是 SPM 添加。当你屏蔽名字时,你会让事情变得更难看????。 SPM 不适用于您,恕我直言。
【参考方案1】:
我通过在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命令创建插件ie时,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"...
-
导航到
ios
目录的根目录,xxxxxx.xcframework
所在的目录
取消选中Copy items if needed
选择Create folder references
检查Pods-Runner
检查您的插件,即。 xxx
点击Add
将xxxxxx.xcframework
嵌入到您的项目中
(这应该允许您运行/发布到真实设备)
-
点击
Pods
方案
在TARGETS
中选择Pods-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
现在您应该能够导入框架并在您的代码中引用它,并且应该也可以正常发布。
希望这会有所帮助,祝你好运。我希望这不会很快再次改变
手指交叉
【讨论】:
感谢您发布您的解决方案!我正在阅读并且有疑问,也许您可以解释一下...我注意到您手动将框架文件添加到 Pods... 在 Flutter 默认的 .gitignore 文件中,此文件夹被列为未版本控制...这真的适用于其他开发人员还是本地解决方案? @siega 只要您嵌入(第 8 步)xcframework,它就可以工作。【参考方案2】:在做了一些研究之后,我发现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 $'\0' 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
【讨论】:
以上是关于如何手动将 .xcframework 添加到 Flutter iOS 插件?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SPM 托管在私有仓库中的 .zip 格式的二进制或 xcFramework
C++ FLTK FL_INPUT 检测何时按下输入然后将文本添加到 FL_TEXT_DISPLAY