LoginSignup
9
3

More than 1 year has passed since last update.

【KMM】sharedモジュールをXCFrameworkとして生成する

Last updated at Posted at 2022-08-29

通常のKMMプロジェクトでは、sharedモジュールのコードをiOS側でも使用できるようにFrameworkとして生成している。
ここでは、sharedモジュールをFrameworkではなくXCFrameworkとして生成する方法をまとめる。

環境

  • KMM:v0.3.3
  • Kotlin:v1.7.0
  • iOS framework distribution:Regular framework
  • NewProjectでKotlin Multiplatform Appを選択した状態とする

デフォルトで生成されるFrameworkについて

NewProjectでKotlin Multiplatform Appを選択してビルドした場合、初期状態ではsharedモジュールをFrameworkとして生成するようになっている。
Frameworkは RootProject/shared/build/bin/に環境ごとに生成される。

  • Arm64用のFramework
  • Simulator Arm64用のFramework
  • X64用のFramework
    スクリーンショット 2022-08-27 16.20.00.png
    Frameworkの場合だとArm64の実機用、Arm64のシミュレータ用など異なったフレームワークを使用することになるが、XCFrameworkを使用することで、統一して1つのフレームワークを使用することが可能になる。

XCFrameworkとして生成する方法

  1. build.gradle.ktsで以下を追加する

    // 追加1
    import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
    ...
    
    kotlin {
    	// 追加2
    	val xcf = XCFramework()
        listOf(
            iosX64(),
            iosArm64(),
            iosSimulatorArm64()
        ).forEach {
            it.binaries.framework {
                baseName = "shared"
                // 追加3
                xcf.add(this)
            }
        }
    }
    
  2. gradlewコマンドでビルドする

    $ ./gradlew build
    
    ...
    BUILD SUCCESSFUL in 1s
    

    するとXCFrameworkを生成する以下のタスクが登録される。

    • assembleXCFramework
    • assembleSharedDebugXCFramework
    • assembleSharedReleaseXCFramework

    実際にタスクが登録されているかは以下のコマンドで確認できる。(DebugとReleaseのコマンドに関しては表示されない)

    $ ./gradlew tasks
    
    ...
    assembleXCFramework - Assemble all types of registered 'shared' XCFramework
    

    assembleXCFrameworkはDebug用とRelease用の両方を生成するため、状況に合わせてDebugのXCFrameworkのみを生成するassembleSharedDebugXCFrameworkを使用するなどすると良さそう。

  3. 生成コマンドを叩く

    $ ./gradlew assembleXCFramework
    

これでXCFrameworkが生成された

生成されたXCFrameworkについて

XCFrameworkは RootProject/shared/build/XCFrameworks/に生成される。
スクリーンショット 2022-08-27 16.49.13.png
前述した通り、XCFrameworkの場合Frameworkの時のようにArm64用・X64用のような環境ごとに生成はされず、1つのXCFrameworkにまとめられている。

Xcode側でXCFrameworkを参照する

  1. Run Scriptの変更
    Build SettingのKMM用のRun Scriptに先ほど生成したassembleXCFrameworkコマンドを設定することで、Xcodeでビルド時にXCFrameworkを生成させる

    # デフォルトが以下
    cd "$SRCROOT/.."
    ./gradlew :shared:embedAndSignAppleFrameworkForXcode
    
    # 変更後
    cd "$SRCROOT/.."
    ./gradlew :shared:assembleSharedDebugXCFramework
    
  2. Framework Search Pathsの変更
    Build SettingのFramework Search Pathsを、XCFrameworkのpathへと変更する

    # デフォルトが以下
    $(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)
    
    # 変更後
    $(SRCROOT)/../shared/build/XCFrameworks
    
  3. Other Linker Flagsの変更
    Buid SettingのOther Linker Flagsに設定されているの以下が不要になるので削除する

    # 削除する
    $(inherited) -framework shared
    
  4. Frameworks, Libraries, and Embedded Contentへの追加
    shared.xcframeworkモジュールを追加する。
    +ボタン → Add Other Filesから、生成された.xcframeworkを選択する
    スクリーンショット 2022-08-27 17.27.55.png

    スクリーンショット 2022-08-27 17.27.31.png

これでXCFrameworkを参照できるようになった。
.swiftファイルでimport sharedするとエラーが出ないことを確認できる。

import shared

XCFrameworkの名前を指定している場合

build.gradle.ktsで XCFrameworkの名前を指定した場合、コマンドは以下のように変更となる

  • assemble<”XCFrameworkの名前”>XCFramework
  • assemble<”XCFrameworkの名前”>DebugXCFramework
  • assemble<”XCFrameworkの名前”>ReleaseXCFramework

<”XCFrameworkの名前”>の箇所は、build.gradle.ktsで XCFramework(””)を生成したときに指定した名前を入れる。

以下の例だと”Hoge”が入っているので

val xcf = XCFramework("Hoge")

assembleHogeXCFrameworkとなる。

XCFrameworkの名前が変わっているので、importするときもsharedではなく、import Hogeになる

import Hoge

終わりに

最近KMMを触る機会が多いのですが、iOSエンジニアがKMMを触るのはGradleだったりAndroid周りの知識だったりが必要なので学習コストが高いなと感じました。
KMM触る時は是非身近なAndroidエンジニアを巻き込むことをお勧めします。

参考

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3