XCFrameworkの作成方法

XCFrameworkはiOSやiPadOS、macOSで利用可能な共有ライブラリです。フレームワークなので、単にバイナリファイルだけではなく、ヘッダーファイルやリソースファイルなどの関連ファイルをすべて含めることができます。SDKを作るときにもお勧めです。

この記事では、XCFrameworkの作成手順やフレームワーク、フレームワークとXCFrameworkの違いについて解説します。

目次

XCFrameworkの作成方法

XCFrameworkはターミナルのコマンドラインツールを使用して作成します。以下のような手順で作成します。

  1. XCFrameworkに含めるフレームワークのアーカイブを作成する。
  2. アーカイブ内のフレームワークをコードサイニングする。
  3. 手順2のアーカイブからXCFrameworkを作成する。
  4. XCFrameworkコードサイニングする。

アーカイブを作成する

XCFrameworkは、異なるプラットフォーム向けのフレームワークを含んでいます。たとえば、iOS/iPadOS用のSDKを作成する場合には、以下のプラットフォーム向けのフレームワークを内部に組み込みます。

  • iOS/iPadOSデバイス用のフレームワーク
  • シミュレータ用のフレームワーク

xcodebuildを使用してアーカイブを作成します。たとえば、上記の2つのプラットフォーム用のアーカイブは以下のように実行します。

xcodebuild archive -project MySDK.xcodeproj -scheme MySDK -destination "generic/platform=iOS" -archivePath "archives/MySDK-iOS"
xcodebuild archive -project MySDK.xcodeproj -scheme MySDK -destination "generic/platform=iOS Simulator" -archivePath "archives/MySDK-iOS_Simulator"

-projectオプションはビルドするプロジェクトファイルを指定します。

-schemeはビルドするスキーム名を指定します。スキーム名は一般的にはターゲット名と同じです。確認するには、Xcodeの「Product」メニューから「Scheme」の「Manage Schemes…」を選択します。スキームの管理画面が表示され、スキーム名も確認できます。

スキーム管理画面

-destinationはビルドするプラットフォームを指定します。本記事執筆時点では以下の値が定義されています。

  • macOS
  • iOS
  • iOS Simulator
  • watchOS
  • watchOS Simulator
  • tvOS
  • tvOS Simulator
  • DriverKit

また、詳細な変種を指定することで、Mac Catalyst用にビルドするなども可能です。-destination "generic/platform=macOS,variant=Mac Catalyst"のように指定します。

-archivePathはアーカイブの出力先を指定します。

フレームワークをコードサイニングする

フレームワークのコードサイニングを行います。以前は、フレームワークやXCFrameworkなどのSDKに対してコードサイニングは不要でした。これはアプリをビルドする際にアプリの電子証明書で一緒にコードサイニングされるためです。しかし、フレームワークがリリースされてから、アプリ開発者に渡るまでの間に改竄されていないことを証明するためにはコードサイニングが必要です。また、2024年の春以降、プライバシーマニフェストに対応する必要があり、プライバシーマニフェストを含むXCFrameworkはコードサイニングが必須となっています。対応していなくてもビルドは可能ですが、AppStoreの審査でリジェクトされる可能性があります。

アーカイブ内のフレームワークをコードサイニングするには、`codesign`を使用します。たとえば、以下のようにします。

codesign --timestamp -f -s "CODESIGN_IDENTITY" archives/MySDK-iOS.xcarchive/Products/Library/Frameworks/MySDK.framework"
codesign --timestamp -f -s "CODESIGN_IDENTITY" archives/MySDK-iOS_Simulator.xcarchive/Products/Library/Frameworks/MySDK.framework"

CODESIGN_IDENTITYには使用する電子証明書を指定します。キーチェーンアクセスで使用する証明書を選択し、名前を調べます。

キーチェーンアクセスで電子証明書の名前を調べる

使用する電子証明書は、AppStore配布用かエンタープライズ配布用かによって異なります。

  • AppStore配布用: Apple Distribution証明書
  • エンタープライズ配布用: iOS Distribution証明書, Mac Distribution証明書など

XCFrameworkを作成する

XCFrameworkを作成するためには、`xcodebuild`を使用して、以下の手順を実行します。これまでの例で示したiOS用アーカイブとiOSシミュレータ用アーカイブからXCFrameworkを作成する方法を紹介します。

xcodebuild -create-xcframework \
    -archive archives/MySDK-iOS.xcarchive -framework MySDK.framework \
    -archive archives/MySDK-iOS_Simulator.xcarchive -framework MySDK.framework \
    -output xcframeworks/MySDK.xcframework

-archiveオプションでXCFrameworkに含めるアーカイブを指定します。-archiveオプションを繰り返して、含めるアーカイブを全て指定します。

-outputは出力するXCFrameworkのパスです。

XCFrameworkをコードサイニングする

最後にXCFrameworkをコードサイニングします。

codesign --timestamp -f -s "CODESING_IDENTITY" xcframework/MySDK.xcframework

これで完成です。作成した`MySDK.xcframework`をSDKとして配布します。

アプリがMySDK.xcframeworkを利用すると、実行するプラットフォームに応じて適切なフレームワークが選択されます。

Frameworkとは?

フレームワークは、Appleプラットフォームで使用される共有ライブラリの一種であり、実体は.frameworkという拡張子を持つディレクトリ形式のバンドルです。

このバンドル内には、以下のようなファイルが含まれています。

  • 共有ライブラリ
  • ヘッダーファイル
  • Swiftモジュール
  • リソースファイル

アプリにフレームワークを組み込むと、アプリ内にコピーされ、実行時にロードされます。

実行時に不要なファイルについて

実行時にはヘッダーファイルは不要です。これらのファイルはXcodeのEmbed Frameworkビルドフェーズで自動的に削除されます。しかし、古いバージョンのXcodeではこの削除が行われませんでした。そのため、古いXcodeを使用している場合は、スクリプトフェーズを追加して、ビルドしたアプリ内のフレームワークからスクリプトでヘッダファイルを削除していました。

フレームワークとXCFrameworkの違い

フレームワークとXCFrameworkの主な違いは、フレームワークが単一のプラットフォーム向けであるのに対し、XCFrameworkは複数のプラットフォームに対応している点です。

さらに、XCFrameworkはフレームワークのコンテナであり、使用時にはフレームワークとしてロードされる共有ライブラリを含んでいます。

XCFramework自体もバンドルであり、拡張子が.xcframeworkのディレクトリです。各プラットフォームごとにディレクトリが作成され、その中にXCFramework作成時に指定したフレームワークが格納されています。たとえば、iOSデバイスとシミュレータ用のフレームワークを含むXCFrameworkは、以下のようなディレクトリ構成になります。

  • ios-arm64/MySDK.framework
  • ios-arm64/dSYMs
  • iOS-arm64_x86_64-simulator/MySDK.framework
  • iOS-arm64_x86_64-simulator/dSYMs
  • Info.plist
  • _CodeSignature

iOS-arm64_x86_64-simulatorディレクトリに含まれるバイナリは、その名前からIntel Mac専用のように見えますが。実際には以下の2つのCPUアーキテクチャをサポートするユニバーサルバイナリです。

  • arm64
  • x86_64

名前はIntel Mac用のように見えますが、Apple Silicon Mac上でシミュレータを使用する際にも、恐らくこのバイナリが使用されていると考えられます。

XCFrameworkが解決した課題

XCFrameworkが存在しなかった時代にSDKを作成する際は、ユニバーサルバイナリを利用していました。当時は、Apple Silicon Macが存在せず、macOS上のシミュレータはx86_64バイナリで動作していました。一方、デバイス用にはarm64やarmバイナリが使用されていました。異なるCPUアーキテクチャを持つこれらのバイナリをユニバーサルバイナリとして1つにまとめることで、実行時に適切なバイナリがロードされていました。

しかし、Apple Silicon Macの登場により、この方法は使用できなくなりました。Apple Silicon Macのシミュレータも、iOSデバイスと同じarm64アーキテクチャを使用しています。ユニバーサルバイナリを使用するには、同じarm64のバイナリを使用しながらも、シミュレータ用とデバイス用は別々にする必要があります。デバイス用とシミュレータ用の2つのバイナリからユニバーサルバイナリを作成すると、複数のarm64が存在することになり、実行時にどのバイナリをロードするか判断できなくなります。

XCFrameworkはこのような問題を解決しました。

参考記事

著書紹介

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次