[iOS] CarthageでもXCFrameworkが使いたい

2021.03.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。きんくまです。

先日 Swift Package Manager(SPM)を使ってライブラリを管理する記事を書きました。
[iOS] Xcode 12でSwift Package Managerを使ってFirebaseのAnalyticsがあるとiPhone実機で実行できない

あるプロジェクトではそれでうまくいっていました。
ただ、別のプロジェクトでもSPMで管理してみようとCarthage+CocoaPodsから変えてみたところ、ビルド時間が長い問題が発生しました。
Clean後のフルビルドで5分かかりました。長いなーと思い、どうしようか考えました。

Carthageは、M1 macとXcode 12の登場からつかいにくい状況が続いていたのですが、XCFrameworkに対応することで使いやすくなっていました。
XCFrameworkを使ったCarthageのビルドにすることで、5分のビルド時間を調子の良い時で2分。通常は3分まで減らすことができました。

あとCarthageでもエラーがおきてしまうライブラリがあるので、その場合はCocoaPodsも併用しています。

参考)XCFramework
xcframeworkを作成する(第1回)

CarthageでXCFrameworkを使う

XCFrameworkはCarthage 0.37.0から利用できます。バージョンが古いときはアップデートしておきます。
Carthageのライブラリをビルドするときのコマンドは --use-xcframeworks オプションをつけます。

carthage update --use-xcframeworks --platform iOS

ビルドされたライブラリを見ると、複数のframeworkが入っていることが確認できます。

以前Carthageを使っていた場合は前のものを削除する

もし以前Carthageを使っていた場合は、公式の手順に沿って以前の設定を削除しておきます。

プロジェクトに設定する

アプリTaget > General > Framworks, Libraries, and Embedded Content
ここにxcframeworkをさきほどビルドしたところからFinderからドラッグドロップで設定します。

ビルドパス

プロジェクトフォルダ/Carthage/Build/XXX.xcframework

基本的にはこれだけで、うまくいくはずです。

追加設定

ただ、私の場合は本番環境をSimulatorで動かそうとしたときに設定を少し変える必要がありました。

参考 Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Xcodeの設定

Project設定 > Excluded Architecturesに

Any iOS Simulator SDK に arm64 を追加

CocoaPodsに設定

このあたりは、ビルドや実行時エラーが出るたびに調べたので、いろいろ混じっています。

post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        # 警告がたくさん出るため
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
        # 起動できるように
        config.build_settings.delete 'ARCHS'
        # ライブラリが見つからないエラー対策
        config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
      end
    end
end

終わったら pods install しておきます。

Test TargetはXCFrameworkではなく通常のframeworkを使った

いろいろとやってみたのですが、Test Targetの方はXCFrameworkがうまく使えませんでした。
なので、こちらについては、これまでのCarthageの設定通りにframeworkを使いました。

ビルドされたXCFrameworkの中に、通常のframeworkが入っています。ios-arm64_i386_x86_64-simulatorがSimulator用です。

Test Targetにドラッグドロップします。

Run Scriptにいつも通り設定します。

/usr/local/bin/carthage copy-frameworks

InputFiles

$(SRCROOT)/Carthage/Build/RxBlocking.xcframework/ios-arm64_i386_x86_64-simulator/XXX.framework

OutputFiles

$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/XXX.framework

これでビルドしてSimulatorが立ち上がり、テストもできるようになりました。

ビルド時間が短くなって良かったです!