🍺

[M1Mac]Carthageを用いてR.swiftを扱う方法

2022/08/30に公開

はじめに

Carthageでライブラリを入れて開発をしているのですが、R.swiftを初めて使う際に機能しなくて困っていました。
色々調べていく際に、M1Macの「Homebrewの場所がIntel製と異なる」という特徴が原因であると発覚したので、報告&改善策としてまとめます。

開発環境

  • M1 macOS Monterey
  • Swift5
  • Xcode: 13.4.1
  • R.swift: 6.1.0(13F100)

R.swiftとは

Swiftプロジェクトで画像、フォント、ストーリーボードなどのリソースを簡単に取得できるようにするライブラリです。

https://github.com/mac-cain13/R.swift

これを導入するメリットは、

  • リソースをキャストせずに使える
  • コンパイル時のチェックにより、誤った文字列でアプリがクラッシュすることがなくなる
  • リソース名が自動補完される

といった点があります。

具体的にSwiftコードで見てみると、

R.swiftなし
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")
R.swiftあり
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.swiftで記述した方が、簡潔にリソースを取得することができます。

R.swiftの導入方法

ここから本題で、Carthageを利用してR.swiftを導入していきます。
Carthageのインストール方法に関しては、CarthageのGitHubコチラの記事をご参照ください。

手順は主に3つあります:

  1. rswiftの自動生成プログラムをインストール
  2. CarthageでR.swiftライブラリを導入
  3. Xcodeへ移り、公式のGitHubのManuallyの2番以降の通りに設定をしていく

以下では、これらを順番に説明していきたいと思います。

rswiftの自動生成プログラムをインストール

Homebrewからrswiftの自動生成プログラムをインストールしてきます。
 Brewfileを利用している方はbrew "rswift"の行をBrewfileに追加、Homebrewを使用している方は、Terminalからbrew install rswiftでインストールできます。

CarthageでR.swiftライブラリを導入

Cartfileに

Cartfile
github "mac-cain13/R.swift.Library"

を追加して、carthage update --use-xcframeworksを実行します。すると、.xcframeworkを作成することができます。
そして、Xcode内のGeneralから"Frameworks, Libraries, and Embedded Content"セクションに、.xcframeworkを追加します。
これで、CarthageでR.swiftライブラリを導入することができました。
しかし、このままではR.swift本来の力を発揮することができないので、R.swiftの設定をしていきます。

公式のGitHubのManuallyの2番以降の通りに設定をしていく

ここからは、公式のGitHubのManuallyの2番を参考に導入していきます。

Xcodeにて、ファイルリストでプロジェクトをクリック。その後、"TARGETS"で "Build Phases"タブをクリックして、左上の+から、New Run Script Phaseを追加します。

次に、Run ScriptCompile Sourcesの上にドラッグします。

そして、以下のスクリプトを貼り付けます。

Run Script
if test -d /opt/homebrew/bin; then
    export PATH=$PATH:/opt/homebrew/bin:/opt/homebrew/sbin
fi
rswift generate "$SRCROOT/R.generated.swift"

"$SRCROOT/rswift"ではなく、rswiftである理由は、先ほどすでにHomebrewでrswiftを導入しているからです。そのため、"$SRCROOT/rswift"で呼び出さなくてもrswiftで呼ぶ出すことが可能です。
また、M1 MacはHomebrewを/opt/homebrewで保存しています。一方、Intel Macは/usr/localに保存されています。現在のXcode13は、Run Scriptを実行した際に/usr/localを参照してしまうため、/opt/homebrewを参照するよう、

if test -d /opt/homebrew/bin; then
    export PATH=$PATH:/opt/homebrew/bin:/opt/homebrew/sbin
fi

を最初の行に追加する必要があります。

最後に、Build PhaseのOutput Filesに、$SRCROOT/R.generated.swiftを追加し、Based on dependency analysisのチェックを外します。

↑のような形になっていればビルド毎にR.swiftを実行することができます。

まとめ

M1 MacでR.swiftを利用する際は、Run Scriptにhomebrewの場所を参照するよう追加のコードを記述する必要がある。
今回はCarthageを用いたR.swiftの導入でしたが、R.swift自体はCarthageでの導入を推奨しておらず、Cocoa Podsでの導入を推奨しているため、CocoaPodsで開発ができるのであれば、そちらをオススメします。

参考文献

https://qiita.com/uhooi/items/82fbdd94bdc467a22422

https://qiita.com/lovee/items/5617cdaa28a470b141c2

おまけ:セットアップ方法

R.swiftで文字列を使用する方法をここで解説します。

プロジェクトディレクトリの配下に.strings拡張子のファイルを配置します。Xcodeでは、右クリック→New file...から追加することができます。

デフォルトのAppDelegate.swiftの同層配下であればディレクトリがネストしていても取得可能です。

message.strings
"one" = "hoge";
"helloSwift" = "Hello Swift!";

一度、command+Bでビルドした後、これをプロジェクト内で使うと

let hogeText = R.string.messages.one()  // hoge
let helloText = R.string.messages.helloSwift() // Hello Swift!

となります。

Discussion