On this page you'll find examples of the kind of resources R.swift supports and how you can use them. We aim to keep this page up to date and complete so this should be a overview of all possibilities.
Call R.validate()
to call all validation methods that R.swift generates, this will check:
- If all images used in storyboards and nibs are available
- If all view controllers with storyboard identifiers can be loaded
- If all custom fonts can be loaded
The R.validate()
method will throw a detailed error about the problems that occur. Note that this method will always perform checks, even in release builds. It’s recommended that validation is done in a testcase.
Example testcase
XCTAssertNoThrow(try R.validate())
R.swift will find both images from Asset Catalogs and image files in your bundle.
Vanilla
let settingsIcon = UIImage(named: "settings-icon")
let gradientBackground = UIImage(named: "gradient.jpg")
With R.swift
let settingsIcon = R.image.settingsIcon()
let gradientBackground = R.image.gradientJpg()
Selecting "Provides Namespace" results in grouping assets:
Use like so:
let image = R.image.menu.icons.first()
Vanilla
let lightFontTitle = UIFont(name: "Acme-Light", size: 22)
With R.swift
let lightFontTitle = R.font.acmeLight(size: 22)
Tip: Also want this for system fonts? Take a look at the UIFontComplete library, has a similar solution for the fonts Apple ships with iOS.
Vanilla
let jsonURL = Bundle.main.url(forResource: "seed-data", withExtension: "json")
let jsonPath = Bundle.main.path(forResource: "seed-data", ofType: "json")
With R.swift
let jsonURL = R.file.seedDataJson()
let jsonPath = R.file.seedDataJson.path()
Vanilla
view.backgroundColor = UIColor(named: "primary background")
With R.swift
view.backgroundColor = R.color.primaryBackground()
Vanilla
let welcomeMessage = NSLocalizedString("welcome.message", comment: "")
let settingsTitle = NSLocalizedString("title", tableName: "Settings", comment: "")
// Formatted strings
let welcomeName = String(format: NSLocalizedString("welcome.withName", comment: ""), locale: NSLocale.current, "Alice")
// Stringsdict files
let progress = String(format: NSLocalizedString("copy.progress", comment: ""), locale: NSLocale.current, 4, 23)
With R.swift
// Localized strings are grouped per table (.strings file)
let welcomeMessage = R.string.localizable.welcomeMessage()
let settingsTitle = R.string.settings.title()
// Functions with parameters are generated for format strings
let welcomeName = R.string.localizable.welcomeWithName("Alice")
// Functions with named argument labels are generated for stringsdict keys
let progress = R.string.localizable.copyProgress(completed: 4, total: 23)
Vanilla
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialTabBarController = storyboard.instantiateInitialViewController() as? UITabBarController
let settingsController = storyboard.instantiateViewController(withIdentifier: "settingsController") as? SettingsController
With R.swift
let storyboard = R.storyboard.main()
let initialTabBarController = R.storyboard.main.initialViewController()
let settingsController = R.storyboard.main.settingsController()
Vanilla
// Trigger segue with:
performSegue(withIdentifier: "openSettings", sender: self)
// And then prepare it:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let settingsController = segue.destination as? SettingsController,
let segue = segue as? CustomSettingsSegue, segue.identifier == "openSettings" {
segue.animationType = .LockAnimation
settingsController.lockSettings = true
}
}
With R.swift
// Trigger segue with:
performSegue(withIdentifier: R.segue.overviewController.openSettings, sender: self)
// And then prepare it:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let typedInfo = R.segue.overviewController.openSettings(segue: segue) {
typedInfo.segue.animationType = .LockAnimation
typedInfo.destinationViewController.lockSettings = true
}
}
Tip: Take a look at the SegueManager library, it makes segues block based and is compatible with R.swift.
Vanilla
let nameOfNib = "CustomView"
let customViewNib = UINib(nibName: "CustomView", bundle: nil)
let rootViews = customViewNib.instantiate(withOwner: nil, options: nil)
let customView = rootViews[0] as? CustomView
let viewControllerWithNib = CustomViewController(nibName: "CustomView", bundle: nil)
With R.swift
let nameOfNib = R.nib.customView.name
let customViewNib = R.nib.customView()
let rootViews = R.nib.customView.instantiate(withOwner: nil)
let customView = R.nib.customView.firstView(owner: nil)
let viewControllerWithNib = CustomViewController(nib: R.nib.customView)
Vanilla
class FaqAnswerController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textCellNib = UINib(nibName: "TextCell", bundle: nil)
tableView.register(textCellNib, forCellReuseIdentifier: "TextCellIdentifier")
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let textCell = tableView.dequeueReusableCell(withIdentifier: "TextCellIdentifier", for: indexPath) as! TextCell
textCell.mainLabel.text = "Hello World"
return textCell
}
}
With R.swift
On your reusable cell Interface Builder "Attributes" inspector panel, set the cell "Identifier" field to the same value you are going to register and dequeue.
class FaqAnswerController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(R.nib.textCell)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let textCell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.textCell, for: indexPath)!
textCell.mainLabel.text = "Hello World"
return textCell
}
}
Vanilla
class RecentsController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
let talkCellNib = UINib(nibName: "TalkCell", bundle: nil)
collectionView?.register(talkCellNib, forCellWithReuseIdentifier: "TalkCellIdentifier")
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TalkCellIdentifier", for: indexPath) as! TalkCell
cell.configureCell("Item \(indexPath.item)")
return cell
}
}
With R.swift
On your reusable cell Interface Builder "Attributes" inspector panel, set the cell "Identifier" field to the same value you are going to register and dequeue.
class RecentsController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.register(R.nib.talkCell)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: R.reuseIdentifier.talkCell, for: indexPath)!
cell.configureCell("Item \(indexPath.item)")
return cell
}
}
Vanilla
let developmentRegion = fatalError("Not available at runtime")
let myTag = "myTag"
With R.swift
Access the development region and any asset tags that are set on the project file.
let developmentRegion = R.project.developmentRegion
let myTag = R.project.knownAssetTags.myTag
With R.swift
Access the values in the entitlement file you embedded. This might differ from the entitlements your app actually has at runtime! But it's greate to get some identifiers in a consistent way.
let appGroupIdentifier = R.entitlements.comAppleSecurityApplicationGroups.groupMyAppGroup
Values under UIApplicationShortcutItems
, UIApplicationSceneManifest
, NSUserActivityTypes
, NSExtension
that are often needed in code are available directly through R.swift.
With R.swift
Access the values in the Info.plist file.
let activity = NSUserActivity(activityType: R.info.nsUserActivityTypes.planTripIntent)