如何手动将 .xcframework 添加到 Flutter iOS 插件?

sie*_*ega 16 podspec flutter podfile flutter-plugin flutter-ios

我正在尝试创建一个 Flutter 插件来使用本机库。我尝试使用的这个库存储在私有存储库中,可以与 Swift 依赖管理器一起使用。

这让我很头痛,因为我无法在我的插件中添加私有存储库依赖项(我找不到在 .podspec 文件中执行此操作的方法),所以我做了什么:

  1. 我已使用 Swift Package Manager 将插件添加到示例项目中
  2. 手动复制MyDependency.xcframework文件夹到MyPlugin/ios文件夹
  3. 在 podspec 文件中引用它,如下所示:
s.preserve_paths = 'MyDependency.xcframework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework MyDependency' }
s.vendored_frameworks = 'MyDependency.xcframework'
Run Code Online (Sandbox Code Playgroud)

这样做我可以在插件的源代码中使用 MyDependency 。

我当前的问题是:这仅适用于 Simulator

在此之前,该项目在真实设备上运行没有任何问题。

这是我每次尝试在真实设备中运行时收到的错误消息: 在此输入图像描述

另外,我直接使用 Swift 依赖管理器中的依赖项进行了测试,并且运行良好。我认为问题在于我将框架添加到插件的方式。

在此输入图像描述

Pie*_*rre 20

我通过将以下几行添加到xxx.podspec

s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
Run Code Online (Sandbox Code Playgroud)

注意/**/*最后的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'
  
  # Inorder to add multiple frameworks
  s.preserve_paths = ['xxxxxxx.xcframework/**/*', 'yyyyyyy.xcframework/**/*']
  s.xcconfig = { 'OTHER_LDFLAGS' => ['-framework xxxxxxx', '-framework yyyyyyy'] }
  s.vendored_frameworks = ['xxxxxxx.xcframework', 'yyyyyyy.xcframework']      

end
Run Code Online (Sandbox Code Playgroud)

确保将xxxxxx.xcframework目录复制到.../xxx/ios/xxxxxx.xcframework(您的插件xxx.podspec所在的位置)


添加xxxxxx.xcframeworkPods方案以便能够导入它

运行flutter命令创建插件时,该Frameworks目录应位于scheme下方,即。Pods

flutter create --org com.xxx --template=plugin --platforms=android,ios -a java -i swift xxx

来源:开发包和插件

(如果没有,请添加)

添加框架1

  1. 导航到Pods方案并右键单击Frameworks
  2. 点击Add Files to "Pods"...

在此输入图像描述

  1. 导航到所在ios目录的根目录xxxxxx.xcframework
  2. 取消选中Copy items if needed
  3. 选择Create folder references
  4. 查看Pods-Runner
  5. 检查你的插件,即。xxx
  6. 点击Add

嵌入xxxxxx.xcframework到您的项目中

(这应该允许您运行/发布到真实设备)

在此输入图像描述

  1. 点击Pods方案
  2. TARGETS选择中Pods-Runner
  3. 单击选项General
  4. 确保xxxxx.xcframework下面存在Frameworks and Libraries(如果没有,请单击 添加+
  5. 改成EmbedEmbed & Sign

在此输入图像描述

  1. 单击您的插件,即。xxx
  2. 确保xxxxx.xcframework下方存在Frameworks and Libraries
  3. 改成EmbedEmbed & Sign

在此输入图像描述

  1. 同样,对于下面Pods方案的两个目标,接下来的步骤应该已经没问题了,但只需检查一下
  2. 点击Build Phases
  3. 点击Link Binary With Libraries
  4. 确保xxxxx.xcframework存在,如果没有添加,请单击+并将其Status设置为Required

现在您应该能够导入框架并在代码中引用它,并且还应该可以完美发布。

希望这有帮助,祝你好运。我希望这不会很快再次改变

手指交叉


sie*_*ega 1

经过一些研究后,我发现一些链接给了我关于真正问题的想法......

为了解决这个问题,我在主项目的构建过程中添加了一个简单的脚本。

该脚本将代码签名添加到内部.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
Run Code Online (Sandbox Code Playgroud)