Of all the iOS libraries I got to know about in the year 2019, R.swift happens to be at the top, for me.
Coming from an android development background, I understand the ease that comes from being able to access drawables (images), colors, fonts, etc simply by using R.drawable.something
, R.font.myFont
or R.color.colorPrimary
. This stuff just makes your life easier as a developer. However, as a native iOS developer, to reference an image, font, color or instantiate a ViewController, you basically have to do something like:
//Color let color = UIColor(hexString: "#59aee9") //Image imageView.image = UIImage(named: "BackgroundImage") //Font let customFont = UIFont(name: "Poppins", size: 14) //Instantiating ViewController let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
Should we talk about errors that come from a typo or even errors that come from a change in Identifiers and so on? These can put you in a lot of unnecessary trouble. Imagine someone mistakenly changing an image name from BackgroundImage
to backgroundImage
, such a simple mistake might cause your image not to be displayed. There are lots more other errors that could come from having to hard-code these texts this way. But there is a solution! What if we can have a fully typed, autocompleted code that has compile-time check which would make sure these images, fonts, colors, etc are present and well-referenced right at compile-time? This is exactly where R.swift comes in.
With R.swift, you get strong typed, autocompleted resources like images, fonts and segues in your Swift projects.
It makes your code that uses resources:
- Fully typed, less casting and guessing what a method will return
- Compile-time checked, no more incorrect strings that make your app crash at runtime
- Autocompleted, never have to guess that image name again.
It is available for installation using Cocoapods, Mint or using the Swift Package Manager. You can find the installation guide here.
While installation is settled, let’s check out some examples to see how it works:
Images
//Vanilla let settingsIcon = UIImage(named: "settings-icon") //R.swift let settingsIcon = R.image.settingsIcon()
Custom Fonts
//Vanilla let lightFontTitle = UIFont(name: "Acme-Light", size: 22) //R.swift let lightFontTitle = R.font.acmeLight(size: 22)
Resource files
//Vanilla let jsonURL = Bundle.main.url(forResource: "seed-data", withExtension: "json") //R.swift let jsonURL = R.file.seedDataJson()
Colors
//Vanilla view.backgroundColor = UIColor(named: "primary background") //R.swift view.backgroundColor = R.color.primaryBackground()
Localized strings
//Vanilla let welcomeMessage = NSLocalizedString("welcome.message", comment: "") //R.swift let welcomeMessage = R.string.localizable.welcomeMessage()
Storyboards
//Vanilla let storyboard = UIStoryboard(name: "Main", bundle: nil) let settingsController = storyboard.instantiateViewController(withIdentifier: "settingsController") as? SettingsController //R.swift let settingsController = R.storyboard.main.settingsController()
Segues
//Vanilla performSegue(withIdentifier: "openSettings", sender: self) //R.swift performSegue(withIdentifier: R.segue.overviewController.openSettings, sender: self)
Nibs
//Vanilla let customViewNib = UINib(nibName: "CustomView", bundle: nil) //R.swift let customViewNib = R.nib.customView()
Reusable table view cells
//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 } }
//R.swift 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 } }
Reusable collection view cells
//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 } }
//R.swift 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 } }
I’m sure you would have seen how easy some of your works would become, using this R.swift library. Why not give it a try? Trust me, you’d feel like refactoring all your code once you see it at work. ?