【iOS】R.Swiftの導入と使い方!静的リソースを安全管理
この記事からわかること
- R.Swiftとは?
- 導入方法と使い方
- 画像やカラーの参照方法
- ローカライズした文字列参照方法
- R.generated.swiftファイルとは?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:16.0
- iOS:18.0
- Swift:5.9
- R.Swift:7.8.0
- macOS:Sonoma 14.6.1
R.Swiftとは?
R.Swiftはプロジェクト内で使用するリソース(画像やローカライズされた文字列など)をタイプセーフに参照、管理するためのSwiftコードを自動的に生成するライブラリです。R.Swiftを使用することでタイプミスの回避や存在しないアセットを参照する可能性を無くしたりとアプリを開発する上で間違いやすいリソースの参照を簡潔に記述することができるようになります。
似たような役割を持っているSwiftGenというものがありますがこれはCLI(Command Line Interface)ツールなのでプロジェクトごとにというより、Mac自体に導入する形になります。
導入とセットアップ方法
プロジェクトにR.Swiftを導入するにはSwift Package Manager(SPM)やCocoa Podsが利用できます。R.Swift7以降からはSPMでの導入が推奨されているのでSPMでの導入手順をまとめていきます。
上部のメニューから「File」>「Add Packages...」をクリックします。
検索欄にhttps://github.com/mac-cain13/R.swift
と入力し「r.swift」を選択して「Add Package」をクリックします。
「RswiftLibrary」のターゲットが設定されていることを確認して「Add Package」をクリックします。
これでライブラリ自体の導入は完了です。
Run Build Tool Plug-insに設定を追加
ビルド実行時にRSwiftのプラグインが実行されるようにRun Build Tool Plug-insに設定を追加します。「Build Phases」>「Run Build Tool Plug-ins」の「+」をクリックします。
「RswiftGenerateInternalResources」を選択して追加します。
この状態で一度ビルドさせようとすると「"RswiftGeneratelnternalResources" must be enabled before it can be used.Enable it now?」というポップアップが出るので「Trust & Enable」をクリックします。
これでR.Swiftの導入とセットアップが完了し静的リソースが型安全に参照できるようになります。
リソースの参照方法
プロジェクト内にカラーや画像などリソースを用意しておきましょう。例えば上記のように定義していた場合は以下のように自動でR
変数を介して参照できるようになります。
VStack {
Image(R.image.app_logo)
Text("Hello")
.foregroundStyle(Color(R.color.accent_color))
}
リソースに定義した名前が単語ごとに-
で繋げている場合は自動でキャメルケースになるようです。
例:accent_color → accentColor
プロパティからはXXXXXResource
型に同名のメソッドからはオプショナルの対象データ型
を参照できます。
R.image.app_logo // ImageResource
R.image.app_logo() // UIImage?
R.color.accent_color // ColorResource
R.color.accent_color() // UIColor?
対象のリソースファイル
画像やカラーだけでなくフォントやローカライズしている文字列、xib
ファイルなども自動で変換してくれるようです。
let icon = UIImage(named: "settings-icon")
let font = UIFont(name: "San Francisco", size: 42)
let color = UIColor(named: "indicator highlight")
let viewController = CustomViewController(nibName: "CustomView", bundle: nil)
let string = String(format: NSLocalizedString("welcome.withName", comment: ""), locale: NSLocale.current, "Arthur Dent")
let icon = R.image.settingsIcon()
let font = R.font.sanFrancisco(size: 42)
let color = R.color.indicatorHighlight()
let viewController = CustomViewController(nib: R.nib.customView)
let string = R.string.localizable.welcomeWithName("Arthur Dent")
R.generated.swiftファイル
リソースに参照できるR
変数はR.Swiftによって自動生成されるR.generated.swift
ファイルに定義されています。
import Foundation
import RswiftResources
private class BundleFinder {}
let R = _R(bundle: Bundle(for: BundleFinder.self))
struct _R {
let bundle: Foundation.Bundle
var color: color { .init(bundle: bundle) }
var image: image { .init(bundle: bundle) }
func color(bundle: Foundation.Bundle) -> color {
.init(bundle: bundle)
}
func image(bundle: Foundation.Bundle) -> image {
.init(bundle: bundle)
}
func validate() throws {
}
struct project {
let developmentRegion = "en"
}
/// This `_R.color` struct is generated, and contains static references to 2 colors.
struct color {
let bundle: Foundation.Bundle
/// Color `accent_color`.
var accent_color: RswiftResources.ColorResource { .init(name: "accent_color", path: [], bundle: bundle) }
}
/// This `_R.image` struct is generated, and contains static references to 1 images.
struct image {
let bundle: Foundation.Bundle
/// Image `app-logo`.
var appLogo: RswiftResources.ImageResource { .init(name: "app-logo", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
}
}
実態のファイルはプロジェクト階層の中ではなくDerivedData
データの中に生成されるようです。
~/Library/Developer/Xcode/DerivedData/プロジェクト名-eceicgeflvpgpvdpfihzgroudiag/SourcePackages/plugins/プロジェクト名.output/プロジェクト名/RswiftGenerateInternalResources/プロジェクト名/Resources/R.generated.swift
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。