はじめに
iOS開発で、Debug用のツールに「FLEX」という便利なものがあります。実務で使ってみて非常に便利だったことと、FLEXについて説明する記事があまりなかったので、本記事を書こうと思いました。
FLEX (Flipboard Explorer) とは
FLEXは、iOS開発で用いられるアプリ内Debugツールです。2022/12月時点で、Githubのリポジトリのスター数が13.3kもつく非常に有名なライブラリです。
Githubのリンク: https://github.com/FLEXTool/FLEX
以下のように、iOSシミュレータ上でFLEXを起動すると、ツールバーが表示され、様々なことを行うことができます。
FLEXのデフォルト機能
- ビューの修正(プロパティの変更・メソッド呼び出しなど)
- ネットワークの通信履歴の確認
- Heap上のオブジェクトの確認
- アドレスからオブジェクトの探索
- iOSシミュレータでショートカットキーの利用(例えば、
↑↓
キーで上下にスクロール)。カスタマイズキーも登録可能。 - ファイルの閲覧
- データベースのテーブル閲覧(SQLite又はRealm)
- 様々な圧力レベルの3Dタッチ
などが挙げられます。詳しくはREADMEを参照してみてください。
個人的に、「ネットワークの通信履歴」を確認できる機能は非常に便利なので、よく利用しています。APIのリクエスト、レスポンスの確認や、リクエストに対するCurlコマンドのコピーもできます。
FLEXで登録した任意の処理を呼び出す
上記の機能に加えて、FLEXは、Debug用に任意の処理を登録することができ、FLEXのMenuからそれらを簡単に実行することができます。
例として、今回はFLEXを用いて「画面遷移」と「APIを叩く」処理を呼び出してみます。
セットアップ
FLEXのインストール
FLEXはSPM, CocoaPods, Carthageなどを用いてインストール可能です。今回はSPMでインストールしていきます。
以下、手順です。
FLEXをDebugモードでのみ有効化
FLEXはDebug用のツールなので、Debugモードの時のみ入れておけば良く、Releaseモードに入れる必要はありません。
そこで、TARGETのBuild Settings > Build Options > Excluded Source File Names
のRelease
の項目に、FLEX*
を追加します。これにより、接頭辞がFLEXとつくファイルがReleaseモードで除外されます。
実装
最終的なソースコード: https://github.com/Toshiyana/FlexExample/tree/main
今回は、DebugToolというクラスを作成し、setupFlexという関数の中にFLEXで呼び出したい処理を追加していきます。
#if DEBUG
import FLEX
import SwiftUI
final class DebugTool {
func setupFlex() {
// 今回は、ここにFLEXで呼び出したい処理を追加していく
}
}
#endif
setupFlex関数に記述した処理を呼び出せるように、Appのイニシャライザを以下のように記述します。
import SwiftUI
@main
struct FlexExampleApp: App {
init() {
#if DEBUG
let debugTool = DebugTool()
debugTool.setupFlex()
#endif
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
また、Rleaseモードで実行されずに、Debugモードでのみ実行されるよう#if DEBUG
と#endif
で囲んでいます。
例1: FLEXを用いて任意の画面に遷移
遷移先の適当なViewをSampleViewとします。
import SwiftUI
struct SampleView: View {
var body: some View {
Text("Sample View")
}
}
struct SampleView_Previews: PreviewProvider {
static var previews: some View {
SampleView()
}
}
そして、setupFlex関数に画面遷移の処理を追加します。
#if DEBUG
import FLEX
import SwiftUI
final class DebugTool {
func setupFlex() {
FLEXManager.shared.registerGlobalEntry(withName: "SmpleViewに画面遷移") { hostViewController in
let controller = UIHostingController(rootView: SampleView())
hostViewController.present(controller, animated: true)
}
}
}
#endif
これで、FLEXを用いてSampleViewの画面に遷移できるようになりました。
iOSシミュレータを起動し、キーボードのf
キーを押してFLEXのツールバーを表示して、Menuから実行できることを確認します。
このように、FLEXに画面遷移の処理を登録して、任意の画面をすぐに確認することができます。
例2: FLEXを用いてAPIを叩く
今回は、GithubのAPIを叩いてみます。簡単に、APIを呼ぶための処理を以下のようにしました。
import Foundation
import Combine
enum GithubAPI {
static func searchRepos(page: Int, perPage: Int) -> AnyPublisher<[Repository], Error> {
let url = URL(string: "https://api.github.com/search/repositories?q=swift&sort=stars&page=\(page)&per_page=\(perPage)")!
return URLSession.shared
.dataTaskPublisher(for: url)
.tryMap { try JSONDecoder().decode(GithubSearchResult.self, from: $0.data).items }
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct GithubSearchResult: Codable {
let items: [Repository]
}
struct Repository: Codable, Identifiable, Equatable {
let id: Int
let name: String
let description: String?
let stargazersCount: Int
enum CodingKeys: String, CodingKey {
case id
case name
case description
case stargazersCount = "stargazers_count"
}
}
そして、setupFlex関数の例1の画面遷移の処理の下に、APIを叩く処理を追加します。
#if DEBUG
import FLEX
import SwiftUI
import Combine
final class DebugTool {
private var subscriptions = Set<AnyCancellable>()
func setupFlex() {
// SmpleViewに画面遷移の処理...(省略)
// APIを叩く処理を追加
FLEXManager.shared.registerGlobalEntry(withName: "GithubAPIを叩く") { _ in
GithubAPI.searchRepos(page: 1, perPage: 30)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print("DEBUG: \(error.localizedDescription)")
}
}) { repositories in
print("DEBUG: \(repositories)")
}
.store(in: &self.subscriptions)
}
}
}
#endif
これで、FLEXを用いてAPIを叩くことができるようになりました。
iOSシミュレータを起動し、キーボードのf
キーを押してFLEXのツールバーを表示して、Menuから実行できることを確認します。
一例として、画面遷移やAPIを叩く処理をFLEXに登録しましたが、任意の処理を登録できるので、その他にも色々な使い方ができると思います。例えば、ログイン、ログアウト、キャッシュのクリアなどの操作を登録しておくのも良いですね!
まとめ
FLEXはDebugに非常に便利なツールなので、使ったことのない人はぜひ使ってみてください!