📦

あらゆるライブラリをSwiftPMで使えるようにする

2022/08/16に公開

Swift Package Manager で 3rd party のライブラリを扱えるようにするには、repository に Package.swift を含めることで解決しますが、repo が公開されていないものや、ビルド済みの framework 形式で配布されている場合にはそのまま Swift PM で扱うことができません。

Swift PM で扱える形式は以下2通りのみです。

  • git clone できるソースコードで、Package.swift が含まれている
  • ローカル / リモートに存在する XCFramework 形式

CocoaPods が存在することで、SwiftPM の導入を阻害し、マルチモジュール化を含めたプロジェクト構成の改良に支障を来します。

今回は、MLKit を例に、CocoaPods でしか利用できないライブラリを SwiftPM で利用できることを検証します。

MLKit の依存関係

MLKit は、iOS 向けの機械学習ライブラリで、CocoaPods 経由でしか入手できず、主要なライブラリはすべて framework 形式で配布されています。

また、歴史的経緯から、Firebase と共通の依存関係を有しており、Swift PM でインストールできる Firebase と共通のライブラリに依存しているものと、していないものがあるため、Package.swift でもれなくダブりなく依存関係を定義する必要があります。

MLKit は以下のような依存関係で構成されています。

上記5つの framework はすべて framework 形式で提供されます。

このうち、MLKitCommon は以下のような依存関係を持ちます。

以上のような前提条件がある Framework を SwiftPM でも利用できるかを検討していきます。

arm64 シミュレーターでビルドするのは諦める

従来の Universal Fat バイナリの framework には、iphoneos 向けアーキテクチャと、iphonesimulator 向けアーキテクチャが混在した FAT バイナリになっています。

iphoneos は昔から arm アーキテクチャで動いており、64 bit のデバイスしか存在しない現在では、arm64 アーキテクチャのみあれば動きます。

一方、iphonesimlator 向けには、従来の Intel Mac では x86_64 アーキテクチャがあればよかったのですが、ARM Mac (M1/M2) では、simulator 向けの arm64 アーキテクチャが必要です。

これを得るための唯一の方法は、framework を ARM Mac でビルドすることです。

ARM Mac の xcodebuild で -sdkiphonesimulator を指定すると、simulator 向けのビルドが行えます。framework の target を対象にビルドを行うと、x86_64, arm64 両方が含まれたバイナリが生成されます。

framework がどういったアーキテクチャで構成されているかは、 lipo コマンドを使うことで調べることができます。

lipo -info **/Pods/XXX/Frameworks/XXX.framework/XXX

output:

Architectures in the fat file: **/Pods/XXX/Frameworks/XXX.framework/XXX are: x86_64 arm64

MLKit の framework には、simulator 向け arm64 アーキテクチャが含まれていないのでこの点は諦める必要があります。提供元に ARM Mac でビルドしてもらうと解決します。

たとえ Simulator 向け arm64 アーキテクチャが存在していなくても、Swift PM の利用に必要な XCFramework を構築することは可能です。

<aside>
📒 既存のiphoneos向けバイナリから、simulator向けバイナリの生成を行う arm64-to-sim というツールや、これを利用した xcfamework-maker というツールがあります。
基本原理は、Mach-Oを変換していくのですが、headerのmagicがMH_MAGIC_64かつ、cputypeがCPU_TYPE_ARM64 のものしか変換できないことが確認されています。

MLImage, MLKitCommon, MLKitVision はその形式となっておらず、利用できなかったことを報告しておきます。

</aside>

CocoaPods で framework をビルドし、XCFramework を作成する

Swift PM に対応していないが、CocoaPods でソースコードからビルドできるものについては、CocoaPods で XCFramework を作成することを検討できます。

CocoaPods はデフォルトの設定ではプロジェクトと統合を行いますが、Option を指定することで、プロジェクトとの統合を行わず、ソースコードをクローンして、Pods.xcodeproj を生成するところまででタスクを終了できます。

参考:

CocoaPods を Workspace に自動統合せずに利用する - 24/7 twenty-four seven

これを活用し、まず Podfile を作成します。

platform :ios, '14.0'

install! 'cocoapods', integrate_targets: false

target 'MLKit' do
  use_frameworks!
  pod 'GoogleMLKit/FaceDetection'
  pod 'GoogleMLKit/BarcodeScanning'
end

// Workaround for code signing in Xcode 14 beta
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
      target.build_configurations.each do |config|
          config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
      end
    end
  end
end

この状態で pod install を実行すると、ソースコードが取得できます。

target を MLKit としていますが、この名前は Pods の Umbrella framework に影響するだけで、今回は使わないので、なんでもいいです。

この状態で、iphonesimulator 向け、iphoneos 向けにそれぞれビルドします。

PODS_ROOT="./Pods"
PODS_PROJECT="$(PODS_ROOT)/Pods.xcodeproj"
SYMROOT="$(PODS_ROOT)/Build"
IPHONEOS_DEPLOYMENT_TARGET = 14.0

build-cocoapods: bootstrap-cocoapods
 @xcodebuild -project "$(PODS_PROJECT)" \
 -sdk iphoneos \
 -configuration Release -alltargets \
  ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=NO SYMROOT="$(SYMROOT)" \
  CLANG_ENABLE_MODULE_DEBUGGING=NO \
  BITCODE_GENERATION_MODE=bitcode \
 IPHONEOS_DEPLOYMENT_TARGET="$(IPHONEOS_DEPLOYMENT_TARGET)"
 @xcodebuild -project "$(PODS_PROJECT)" \
 -sdk iphonesimulator \
 -configuration Release -alltargets \
  ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=NO SYMROOT="$(SYMROOT)" \
  CLANG_ENABLE_MODULE_DEBUGGING=NO \
  BITCODE_GENERATION_MODE=bitcode \
 IPHONEOS_DEPLOYMENT_TARGET="$(IPHONEOS_DEPLOYMENT_TARGET)"

上記の設定では、Pods/Pods/Build/<configuration>-<sdk> に framework がそれぞれビルドされます。

ARM Mac でビルドしていれば、すでに XCFramwork を生成できる条件は揃っているので、xcodebuild で XCFramework を生成していきます。

create-xcframework:
 @rm -rf GoogleMLKit
 @xcodebuild -create-xcframework \
  -framework Pods/Pods/Build/Release-iphonesimulator/GoogleToolboxForMac/GoogleToolboxForMac.framework \
  -framework Pods/Pods/Build/Release-iphoneos/GoogleToolboxForMac/GoogleToolboxForMac.framework \
  -output GoogleMLKit/GoogleToolboxForMac.xcframework
 @xcodebuild -create-xcframework \
  -framework Pods/Pods/Build/Release-iphonesimulator/GoogleUtilitiesComponents/GoogleUtilitiesComponents.framework \
  -framework Pods/Pods/Build/Release-iphoneos/GoogleUtilitiesComponents/GoogleUtilitiesComponents.framework \
  -output GoogleMLKit/GoogleUtilitiesComponents.xcframework
 @xcodebuild -create-xcframework \
  -framework Pods/Pods/Build/Release-iphonesimulator/Protobuf/Protobuf.framework \
  -framework Pods/Pods/Build/Release-iphoneos/Protobuf/Protobuf.framework \
  -output GoogleMLKit/Protobuf.xcframework
 @xcframework-maker/.build/release/make-xcframework \
 -ios ./Pods/MLImage/Frameworks/MLImage.framework \
 -output GoogleMLKit
 @xcframework-maker/.build/release/make-xcframework \
 -ios ./Pods/MLKitBarcodeScanning/Frameworks/MLKitBarcodeScanning.framework \
 -output GoogleMLKit
 @xcframework-maker/.build/release/make-xcframework \
 -ios ./Pods/MLKitCommon/Frameworks/MLKitCommon.framework \
 -output GoogleMLKit
 @xcframework-maker/.build/release/make-xcframework \
 -ios ./Pods/MLKitFaceDetection/Frameworks/MLKitFaceDetection.framework \
 -output GoogleMLKit
 @xcframework-maker/.build/release/make-xcframework \
 -ios ./Pods/MLKitVision/Frameworks/MLKitVision.framework \
 -output GoogleMLKit

xcodebuild -create-xcframework を利用した XCFramework では、今 CocoaPods から生成した non-FAT な Framework から XCFramework を生成します。

xcframework-makerを利用した方は、CocoaPods 経由でダウンロードされたビルド済みの FAT バイナリから、arch をそれぞれ extract してから XCFramework を生成しています。(中間ビルド生成物を置くのが面倒なので利用しただけで、lipo -extract <arch> を事前に実行しているのと変わりません)

このようにしてそれぞれの XCFramework を生成します。

今回のバイナリの一部はすでに FAT オブジェクト(.o)になっており、static archive になっていませんでした。そのため、XCFramework を生成したあと、オブジェクトをアーカイブし直すという作業が発生します。

cd ./GoogleMLKit/MLKitBarcodeScanning.xcframework/ios-arm64/MLKitBarcodeScanning.framework/
mv MLKitBarcodeScanning{,.o}
ar r MLKitBarcodeScanning MLKitBarcodeScanning.o
ranlib MLKitBarcodeScanning
rm MLKitBarcodeScanning.o

これを行わないと、Static Framework なのに Xcode が Embed すべき Framework と判断して、ipa ファイル内にコピーしてしまい、Info.plist が存在しないのでインストールに失敗するという事象がおきていました。(Thanks to @kateinoigakukun and @kishikawakatsumi)

Package を作成する

Pods に含まれているそれぞれの xcconfig をみながら、Package.swift に依存関係を定義していきます。

// swift-tools-version: 5.6

import PackageDescription

let package = Package(
  name: "GoogleMLKitSwiftPM",
  platforms: [.iOS(.v14)],
  products: [
    .library(
      name: "MLKitBarcodeScanning",
      targets: ["MLKitBarcodeScanning", "MLImage", "MLKitVision", "Common"]),
    .library(
      name: "MLKitFaceDetection",
      targets: ["MLKitFaceDetection", "MLImage", "MLKitVision", "Common"]),
  ],
  dependencies: [
    .package(url: "https://github.com/google/promises.git", from: "2.1.0"),
    .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.19.0"),
    .package(url: "https://github.com/google/GoogleDataTransport.git", from: "9.1.4"),
    .package(url: "https://github.com/google/GoogleUtilities.git", from: "7.7.1"),
    .package(url: "https://github.com/google/gtm-session-fetcher.git", from: "1.7.2"),
    .package(url: "https://github.com/firebase/nanopb.git", .upToNextMinor(from: "2.30909.0")),
  ],
  targets: [
    .binaryTarget(name: "MLImage", path: "GoogleMLKit/MLImage.xcframework"),
    .binaryTarget(
      name: "MLKitBarcodeScanning", path: "GoogleMLKit/MLKitBarcodeScanning.xcframework"),
    .binaryTarget(name: "MLKitCommon", path: "GoogleMLKit/MLKitCommon.xcframework"),
    .binaryTarget(name: "MLKitFaceDetection", path: "GoogleMLKit/MLKitFaceDetection.xcframework"),
    .binaryTarget(name: "MLKitVision", path: "GoogleMLKit/MLKitVision.xcframework"),
    .binaryTarget(name: "GoogleToolboxForMac", path: "GoogleMLKit/GoogleToolboxForMac.xcframework"),
    .binaryTarget(
      name: "GoogleUtilitiesComponents", path: "GoogleMLKit/GoogleUtilitiesComponents.xcframework"),
    .binaryTarget(name: "PromisesObjC", path: "GoogleMLKit/PromisesObjC.xcframework"),
    .binaryTarget(name: "Protobuf", path: "GoogleMLKit/Protobuf.xcframework"),
    .target(
      name: "Common",
      dependencies: [
        "MLKitCommon",
        "GoogleToolboxForMac",
        "GoogleUtilitiesComponents",
        "PromisesObjC",
        "Protobuf",
        .product(name: "GULAppDelegateSwizzler", package: "GoogleUtilities"),
        .product(name: "GULEnvironment", package: "GoogleUtilities"),
        .product(name: "GULISASwizzler", package: "GoogleUtilities"),
        .product(name: "GULLogger", package: "GoogleUtilities"),
        .product(name: "GULMethodSwizzler", package: "GoogleUtilities"),
        .product(name: "GULNSData", package: "GoogleUtilities"),
        .product(name: "GULNetwork", package: "GoogleUtilities"),
        .product(name: "GULReachability", package: "GoogleUtilities"),
        .product(name: "GULUserDefaults", package: "GoogleUtilities"),
        .product(name: "GTMSessionFetcher", package: "gtm-session-fetcher"),
        .product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
        .product(name: "nanopb", package: "nanopb"),
      ]),
  ]
)

ポイントとしては、Firebase でも利用している Dependency は、SwiftPM のものを定義していることです。こうすることで、Firebase と共通の module を利用することになるので、Symbol が重複しません。

ビルド生成物を確認しても Object File や Framework が重複していないことがわかります。

4baaec0f1590-20220816

Framework をプロジェクトに組み込む

これで framework が生成され、Package.swift に記載でき、プロジェクトに Link できるようになりました。

成果物

https://github.com/d-date/google-mlkit-swiftpm

まとめ

提供元が SwiftPM に対応しない場合にこちらでできることを検証し、SwiftPM で対応できることを確認しました。ビルド済みフレームワークを arm64 simulator に対応するには、提供元で ARM Mac でビルドしてもらう必要がありますが、ソースコードが落とせる場合は Framework をビルドすることで、XCFramework に変換することが可能であることを確認しました。

Appendix: Bundle の取り扱い

Objective-C の頃からリソースをランタイムで読み込むための手法として、.bundle 拡張子のバンドルにリソースを配置するということが行えました。こうすると Asset ひとつひとつに対してターゲットに追加する必要はないのでお手軽なのですが、残念ながらこの形式は Swift PM で直接扱うことはできません。

正しく実装すると、各 module に対応した形で、それぞれのフォルダにリソースを配置するというのが正しいのですが、今回のように呼び出し元が Bundle.main 経由でアクセスしている場合にはクラッシュの原因となるので、おとなしくメインターゲットの Build Phase でコピーします。

Acknowledgements

今回のトラブルシューティングにあたり、@kateinoigakukun さんと@kishikawakatsumi さんには、その卓越した経験と知識により、エラーの解消に導いていただきました。また、@tarunon さんにもいち早くコメントに反応いただき、一緒に解決方法を考えていただきました。みなさんに対して感謝の意を表します。わいわいと楽しめました。ありがとうございました。

トラブルシューティング

@kishikawakatsumi, @kateinoigakukun さんによるトラブルシューティングです。

Kishikawa Katsumi:

MLKitFaceDetection.frameworkMLKitBarcodeScanning.framework は Static Framework だけど、アプリケーションパッケージ(Example.app)に含まれてしまっていることが直接の原因だと思う。再現方法は、上記の手順(https://date.notion.site/WIP-MLKit-SwiftPM-1f037fc18c834898851fc8d091dce613)を一通りやって、https://github.com/d-date/google-mlkit-swiftpmのワークスベースを開いてビルドします。すると Example.app は生成されるけれども、デバイスへのインストール時に

Could not inspect the application package.
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103

のようなエラーでインストールに失敗する。

発生していたエラー:

Details

Unable to install "Example"
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103
User Info: {
    DVTErrorCreationDateKey = "2022-08-15 15:09:35 +0000";
    IDERunOperationFailingWorker = IDEInstalliPhoneLauncher;
}
--
Could not inspect the application package.
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402653103
User Info: {
    DVTRadarComponentKey = 282703;
    MobileDeviceErrorCode = "(0xE8000051)";
    "com.apple.dtdevicekit.stacktrace" = (
 0   DTDeviceKitBase                     0x00000001116382bc DTDKCreateNSErrorFromAMDErrorCode + 300
 1   DTDeviceKitBase                     0x000000011166c3c0 __90-[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:]_block_invoke + 136
 2   DVTFoundation                       0x0000000106b9e530 DVTInvokeWithStrongOwnership + 76
 3   DTDeviceKitBase                     0x000000011166c144 -[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:] + 1196
 4   IDEiOSSupportCore                   0x0000000110c2fd90 __118-[DVTiOSDevice(DVTiPhoneApplicationInstallation) processAppInstallSet:appUninstallSet:installOptions:completionBlock:]_block_invoke.147 + 2328
 5   DVTFoundation                       0x0000000106ca87d4 __DVT_CALLING_CLIENT_BLOCK__ + 16
 6   DVTFoundation                       0x0000000106ca9240 __DVTDispatchAsync_block_invoke + 152
 7   libdispatch.dylib                   0x000000018bb4a5f0 _dispatch_call_block_and_release + 32
 8   libdispatch.dylib                   0x000000018bb4c1b4 _dispatch_client_callout + 20
 9   libdispatch.dylib                   0x000000018bb538a8 _dispatch_lane_serial_drain + 668
 10  libdispatch.dylib                   0x000000018bb54404 _dispatch_lane_invoke + 392
 11  libdispatch.dylib                   0x000000018bb5ec98 _dispatch_workloop_worker_thread + 648
 12  libsystem_pthread.dylib             0x000000018bd0c360 _pthread_wqthread + 288
 13  libsystem_pthread.dylib             0x000000018bd0b080 start_wqthread + 8
);
}
--

Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : {
    "device_model" = "iPhone13,4";
    "device_osBuild" = "15.6 (19G71)";
    "device_platform" = "com.apple.platform.iphoneos";
    "launchSession_schemeCommand" = Run;
    "launchSession_state" = 1;
    "launchSession_targetArch" = arm64;
    "operation_duration_ms" = 3559;
    "operation_errorCode" = "-402653103";
    "operation_errorDomain" = "com.apple.dt.MobileDeviceErrorDomain";
    "operation_errorWorker" = IDEInstalliPhoneLauncher;
    "operation_name" = IDEiPhoneRunOperationWorkerGroup;
    "param_consoleMode" = 0;
    "param_debugger_attachToExtensions" = 0;
    "param_debugger_attachToXPC" = 1;
    "param_debugger_type" = 5;
    "param_destination_isProxy" = 0;
    "param_destination_platform" = "com.apple.platform.iphoneos";
    "param_diag_MainThreadChecker_stopOnIssue" = 0;
    "param_diag_MallocStackLogging_enableDuringAttach" = 0;
    "param_diag_MallocStackLogging_enableForXPC" = 1;
    "param_diag_allowLocationSimulation" = 1;
    "param_diag_checker_tpc_enable" = 1;
    "param_diag_gpu_frameCapture_enable" = 0;
    "param_diag_gpu_shaderValidation_enable" = 0;
    "param_diag_gpu_validation_enable" = 0;
    "param_diag_memoryGraphOnResourceException" = 0;
    "param_diag_queueDebugging_enable" = 1;
    "param_diag_runtimeProfile_generate" = 0;
    "param_diag_sanitizer_asan_enable" = 0;
    "param_diag_sanitizer_tsan_enable" = 0;
    "param_diag_sanitizer_tsan_stopOnIssue" = 0;
    "param_diag_sanitizer_ubsan_stopOnIssue" = 0;
    "param_diag_showNonLocalizedStrings" = 0;
    "param_diag_viewDebugging_enabled" = 1;
    "param_diag_viewDebugging_insertDylibOnLaunch" = 1;
    "param_install_style" = 0;
    "param_launcher_UID" = 2;
    "param_launcher_allowDeviceSensorReplayData" = 0;
    "param_launcher_kind" = 0;
    "param_launcher_style" = 0;
    "param_launcher_substyle" = 0;
    "param_runnable_appExtensionHostRunMode" = 0;
    "param_runnable_productType" = "com.apple.product-type.application";
    "param_runnable_type" = 2;
    "param_testing_launchedForTesting" = 0;
    "param_testing_suppressSimulatorApp" = 0;
    "param_testing_usingCLI" = 0;
    "sdk_canonicalName" = "iphoneos16.0";
    "sdk_osVersion" = "16.0";
    "sdk_variant" = iphoneos;
}
--

System Information

macOS Version 12.4 (Build 21F79)
Xcode 14.0 (21330) (Build 14A5294e)
Timestamp: 2022-08-16T00:09:35+09:00

このとき、デバイスのログを見てみると(Xcode から Open Console、だっけ)上記に書いたように Console を開いて、インストールしようとしているデバイスのログの受信を開始して、再度インストールしようとすると、こういうエラーが出ているのがわかる。

0x16d5ab000 -[MIBundle _validateWithError:]: 47: Failed to load Info.plist from bundle at path /var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.WVoNf1/extracted/Example.app/Frameworks/MLKitBarcodeScanning.framework; Extra info about "/var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.WVoNf1/extracted/Example.app/Frameworks/MLKitBarcodeScanning.framework/Info.plist": Couldn't stat /var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.WVoNf1/extracted/Example.app/Frameworks/MLKitBarcodeScanning.framework/Info.plist: No such file or directory

(ログは膨大なので Example.appなどのキーワードでログをフィルタすると良い。その上で installdプロセスが出力しているログを探すと見つかる。)
これはアプリに含まれる Framework は Info.plist がないとダメなのだけど、それが無いというエラー(だと思う)。つまりこの Framework は Static Framework なのでアプリケーションパッケージに Embed されることを想定してない(ので Info.plist もない)。
ひとまずそれが原因であることを確認するために、Xcode から Products/Example.appを Show Finder して、 Example.app パッケージを Show Contents して Frameworks フォルダからMLKitFaceDetection.frameworkMLKitBarcodeScanning.framework を削除します。

2つの Framework を取り除いた Example.appを直接 Xcode の Device and Simulators のインストールしたいデバイスのところに Drag & Drop します。

これはインストールに成功するはずです。2つの Framework を取り除かずに同様の操作をすると、同じエラーで失敗します(メッセージも同じ。Xcode がやってることを GUI でやっているだけ)
なので直接の原因は Static Framework(正確にいうと Info.plist が含まれていない Framework)をアプリケーションパッケージに含めてしまっていること、だと思います。

直し方はちょっとよくわからない。SwiftPM になんか Embed させない設定があるならそれが良さそう。もしくは Static Link を指定したりできないだろうか。

最悪、Xcode の Script Phase あたりで Framework を取り除く、という操作をすると成功すると思う。

d_date:

で、2つの Framework を取り除いた Example.app を直接 Xcode の Device and Simulators のインストールしたいデバイスのところに Drag & Drop します。

これは取り除いたあとに Run without Building (^ + ⌘ + R)でも成功します (読者向け)

kateinoigakukun:

通常 Static Framework の XCFramework を作る場合、XXX.framework/XXX
は static archive ファイルになっているはずなんですが、MLKitBarcodeScanning はオブジェクトファイルになっているのがおかしそうです。

d_date:

Podfile で use_framework!してるのがよくない?

Kishikawa Katsumi:

ダウンロードしてるだけだからそこは関係ないと思う。

d_date:

たしかに
Kishikawa Katsumi:
CocoaPods は https://dl.google.com/dl/cpdc/bfc93c9fa703fe9e/MLKitBarcodeScanning-2.1.0.tar.gz
を落としてくるだけ(他の人のために書いています)。

kateinoigakukunAugust 16, 2022 2:05 AMAugust 16, 2022 2:05 AM

XCFramework の作り方ですね。元の Pods 配下にインストールされる MLKitBarcodeScanning は既に fatオブジェクト.o)になっていて、make-xcframework がオブジェクトとして分離してしまっているので、そこでアーカイブし直せば良いと思います

Kishikawa KatsumiAugust 16, 2022 2:06 AMAugust 16, 2022 2:06 AM

ar MLKitBarcodeScanning、で.a にしたらいいのかな?(コマンドはうろ覚え)

kateinoigakukunAugust 16, 2022 2:06 AMAugust 16, 2022 2:06 AM

ためしてみます

お、MLKitBarcodeScanning をアーカイブにしたら embed されなくなってますね。

kateinoigakukunAugust 16, 2022 2:11 AMAugust 16, 2022 2:11 AM

やった手順をかきます

August 16, 2022 2:13 AMAugust 16, 2022 2:13 AMAugust 16, 2022 2:13 AM**

make run で MLKitBarcodeScanning.xcframework を作った後、

cd ./GoogleMLKit/MLKitBarcodeScanning.xcframework/ios-arm64/MLKitBarcodeScanning.framework/
mv MLKitBarcodeScanning{,.o}
ar r MLKitBarcodeScanning MLKitBarcodeScanning.o
ranlib MLKitBarcodeScanning
rm MLKitBarcodeScanning.o

を実行してクリーンビルド

MLKitFaceDetection にも同様の作業をするとインストールできるようになりました。

というわけで、xcframework-maker にオブジェクトライブラリの場合に ↑ のステップを追加するのが良さそうですね

Kishikawa KatsumiAugust 16, 2022 2:19 AMAugust 16, 2022 2:19 AM

なかなか手応えのあるトラブルシューティングだった。チームプレイって感じだ。

Discussion