4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

and factory.incAdvent Calendar 2024

Day 17

SwiftPackageからSchemeを取得する

Last updated at Posted at 2024-12-16

はじめに

ビルド環境の切り替えにSchemeを利用しているプロジェクトは結構あると思います。
接続先の変更やMockへの差し替えなど行うのに便利です。

私のプロジェクトでは環境ごとにSchemeを分けており、SwiftPackageを用いたマルチモジュール化を行っていました。

その中でSwiftPackageからSchemeを取得することができずに困ったので、対応法を共有しておきます。

概要

マルチモジュール化の中でInfra層をSwift Packageに切り分けていました。

Infra層でAPIの接続先を切り替えたかったのですが、Active Compilation Conditionsで指定している値(DEBUG/STG/RELEASE)などをSwift Packageから取得することができませんでした。

スキームを取得するためのSwiftPackageの作成

結論から言うと、スキームの情報を取得するために新規でSwiftPackageを作成しました。

SwiftPackage側からアプリモジュールの情報を直接参照することはできないので、起動時などに参照したいSwiftPackage側に渡してあげる必要があります。

例で言うとInfra層に直接情報を渡してあげても良いのですが、マルチモジュール化を進めていく中で他のモジュールでも必要になる可能性が高いため、今回は独立したSwiftPackageを作成して他モジュールから参照する形にしました。

Configurationの定義

作成したSwiftPackageに以下を記述します。
まずスキームごとにenumのcaseで下記のように定義しておきます。

public enum SchemeConfiguration {
    case debug
    case staging
    case release
}

Schemeを渡す

利用する側で下記のProviderを用いてスキームにアクセスできるように定義します。

public struct SchemeConfigurationProvider {
    // 内部で保持する変数
    private static var _config: SchemeConfiguration?

    /// 初期化用
    public static func initialize(config: SchemeConfiguration) {
        self._config = config
    }

    /// スキーム情報を取得するプロパティ
    public static var config: SchemeConfiguration {
        guard let config = _config else {
            fatalError("SchemeConfigurationProvider not initialized.")
        }
        return config
    }
}

AppDelegateでの初期化処理

上記でSwiftPackage側の定義は完了ですが、そのままでは使えません。
SchemeConfigurationProviderの初期化処理でアプリ側からActive Compilation Conditionsなどで定義している値を利用してスキームを渡してあげる必要があります。

/// Schemeに応じたConfiguraionを渡す
func setupSchemeConfiguration() {
    var config: SchemeConfiguration {
        #if DEBUG
        return .debug
        #elseif STG
        return .staging
        #elseif RELEASE
        return .release
        #else
        fatalError("Unknown configuration")
        #endif
    }
    SchemeConfigurationProvider.initialize(config: config)
}

起動時に渡したいので、AppDelegateのdidFinishLaunchingWithOptionsで呼んであげればOKです。あとは利用箇所でSwiftPackageをimportして下記のようにアクセスすれば問題なくスキームごとの値を取得することができるようになりました。

import SchemeConfig

enum APIConfig {
    static let hostURL: String = {
        switch SchemeConfigurationProvider.environment {
        case .debug:
            return "https://hogehoge-debug.com/"
        case .staging:
            return "https://hogehoge-stg.com/"
        case .release:
            return "https://hogehoge.com/"
        }
    }()
}

最後に

SwiftPackage側から取得する方法が何かしらあるはずと思って探していて詰まったのですが、シンプルにApp側から渡してあげればいいだけでした。

SwiftPackageとSchemeを利用しているプロジェクトがあれば参考にしてみてください!

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?