3
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?

More than 1 year has passed since last update.

設定画面からアプリの処理を切り分ける

Posted at

環境

  • Xcode 14.2

Settings.bundleを追加

File」→「New」→「File...」から「Settings Bundle」を選択する

Root.plistの変更

  1. Settings.bundle内にあるRoot.plistを編集する
  2. Preference ItemsにToggle Switchを追加する
    3. Title、Identifierを適当に設定する

Configファイルを作成

  1. UserDefaultに保存するソースコードを追加する
UserDefaultConfig.swift
import Foundation

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultValue: T

    var wrappedValue: T {
        get {
            UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

enum UserDefaultConfig {
    // UserdefaultのkeyはPreference Itemsで設定したIdentifierにする
    @UserDefault(key: "IS_STUB", defaultValue: false)
    static var isStub: Bool
}

上記の設定で、設定画面にパラメータが追加される

UserDefaultの値によって処理を切り分ける

例)レスポンスでStubを返すか、そのままAPIに投げる

LoginModel
import Foundation

protocol LoginModelInput: AnyObject {
    func login(loginInfo: LoginInfo) async throws -> LoginResponse
}

class LoginModel: LoginModelInput {
    func login(loginInfo: LoginInfo) async throws -> LoginResponse {
        if UserDefaultConfig.isStub {
            StubURLProtocol.requestHandler = { request in
                let response = HTTPURLResponse(
                    url: request.url!, statusCode: 200, httpVersion: "HTTP/2", headerFields: [:]
                )!
                guard
                    let jsonDataURL = Bundle.main.url(forResource: "sample", withExtension: "json"),
                    let jsonData = try? String(contentsOf: jsonDataURL)
                else {
                    fatalError("sample.json not found")
                }
                let data = jsonData.data(using: .utf8)
                return (response, data)
            }

            // URLSession を作る
            let config = URLSessionConfiguration.default
            config.protocolClasses = [StubURLProtocol.self]
            let session = URLSession(configuration: config)

            // APIClient を作る
            let client = APIClient(session: session)

            // request 投げる
            let request = LoginInfoRequest(logInfo: loginInfo)
            let response = try await client.send(request)

            return response
        } else {
            do {
                let request = LoginInfoRequest(logInfo: loginInfo)
                let response = try await APIClient().send(request)
                return response
            } catch APIError.networkError {
                fatalError("ネットワークエラー")
            } catch APIError.decodingError {
                fatalError("デコードエラー")
            }
        }
    }
}

注意点

このままだとリリースビルドをした際にも開発用のパラメータが出てしまうため、Active Compilation Conditionsを用いて、Build Phaseの一番最後にRelese Buildの際にはSettings.bundleを削除するScriptを作成する必要がある

3
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
3
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?