Freely inspired by R.swift (Thank you, guys!): get autocompleted localizable strings, asset catalogue images names and storyboard objects.
You can have:
-
Compile time check: no more incorrect strings that make your app crash at runtime
-
Autocompletion: never have to guess that image name again
CocoaPods is the recommended way of installation, as this avoids including any binary files into your project.
-
Add
pod 'R.objc'
to your Podfile and runpod install
-
In XCode, click on your project in the Project Navigator
-
Choose your target under
TARGETS
, click theBuild Phases
tab and add aNew Run Script Phase
by clicking the little plus icon in the top left -
Drag the new
Run Script
phase above theCompile Sources
phase, expand it and paste the following script:"${PODS_ROOT}/R.objc/Robjc" -p "$SRCROOT"
(after -p option, you have to specify the root folder of your project, from where to scan your code)
-
Build your project; in Finder you will now see
R.h
andR.m
files in the$SRCROOT
folder: drag them into your project and uncheckCopy items if needed
-
Repeat point 3 and 4 for every target in your project
-
Download latest version from the releases section
-
Unzip in a folder anywhere you want.
-
In XCode, click on your project in the Project Navigator
-
Choose your target under
TARGETS
, click theBuild Phases
tab and add aNew Run Script Phase
by clicking the little plus icon in the top left -
Drag the new
Run Script
phase above theCompile Sources
phase, expand it and paste the following script:"<path to the unzipped folder>/Robjc" -p "$SRCROOT"
(we suggest to unzip the folder somewhere within your project folder, in order to use the
$SRCROOT
shortcut for the path. Don't add anything to your Xcode project, or it won't build anymore) (after -p option, you have to specify the root folder of your project, from where to scan your code) -
Build your project; in Finder you will now see
R.h
andR.m
files in the$SRCROOT
folder: drag them into your project and uncheckCopy items if needed
-
Repeat point 3 and 4 for every target in your project
At every build, the generated file will update automatically and there's no need to do anything.
Normally, you would write code like this:
[self.buttonProceed setTitle:NSLocalizedString(@"home_proceed", nil) forState:UIControlStateNormal];
self.welcomeLabel.text = [NSString stringWithFormat:NSLocalizedString(@"home_title_welcome", nil), @"John"]; //"hello %@"
self.radioButtonImageView.image = selected ? [UIImage imageNamed:@"checkedRadioButton"] : [UIImage imageNamed:@"uncheckedRadioButton"];
Now you can write
[self.buttonProceed setTitle:R.string.localizable.homeProceed forState:UIControlStateNormal];
self.welcomeLabel.text = [R.string.localizable homeTitleWelcome:@"John"];
self.radioButtonImageView.image = selected ? R.image.checkedRadioButton : R.image.uncheckedRadioButton;
You can add these options to customize R.objc behaviour:
-
-p
(or--path
): MANDATORY path to the root of the project or from where you want the scan to begin -
-e
(or--excluded
): excluded dir path; all dirs within this path will be excluded; you can use-e
option more than once, e.g.-e $(SRCROOT)/Pods
-e $(SRCROOT)/Carthage
-
-v
(or--verbose
): verbose logging -
-s
(or--sysdata
): for internal use only -
-r
(or--refactor
): R.objc will replace all occurrences of NSLocalizedString with the correctR.string
reference -
--skip-strings
: jump the strings step -
--skip-images
: jump the images step -
--skip-themes
: jump the themes step. Use this to avoid Giotto import error -
--skip-storyboards
: jump the storyboards step -
--skip-segues
: jump the segues step
You can access localized strings with compile time checked keys usign keypath
R.string.localizable.commonWarning
The keypath is composed like this: R.string.<string_file_name>.<string_key>
If you check the documentation of the string (alt+click) you'll see the original key and all the localized values
You can access localized strings containing a string with format, passing directly parameters and obtaining the composed value
[R.string.localizable alertMessage:@"username" value2:4.7];
The methods is named like the key of the localized string with parameter 1
implicit; all other parameters are named value and numbered progressively.
Formats in the string are mapped by the objects the represent (eg. %f
is
mapped as a double
, %@
ad an id
)
All images will be mapped, those in an asset catalogue and those outside.
You can access by
R.image.navbarLogo
You'll get a UIImage*
directly.
All storyboards in the bundle will be mapped in a
R.storyboard.<storyboard_name>
path. You'll have an
instantiateInitialViewController
method and a method to instantiate a view
controller for every storyboard identifier found.
Example:
[R.storyboard.main instantiateInitialViewController];
[R.storyboard.main loginViewController];
Like storyboards, in the segue object you'll find a list of all view controllers which are source of a segue. Starting from them, you can access their segues and get the segue identifier or perform segue passing source and sender objects
Example:
R.segue.myViewController.goToNextSegue.identifier // identifier of the segue
[R.segue.myViewController.goToNextSegue.identifier performWithSource:self sender:userInfo]; // perform segue
If you are using Giotto Theme Manager, R.objc will search for theme_*.plist files in your project. You can then access to all your constants and styles.
Example:
[R.theme.styles.myStyle applyTo:self]; // apply the style MyStyle to object self
R.theme.constants.COLOR_TEXT_LIGHT // reference to a constant in the theme
-
You may want to exclude Pods and/or Carthage dirs. To do so pass:
-e $(SRCROOT)/Pods -e $(SRCROOT)/Carthage
-
R.h:2:9: Module 'Giotto' not found
Addpod 'Giotto'
to Podfile or pass--skip-themes
parameter. -
Duplicate interface definition for class 'R<some-resource-name>'
Check in the filesystem if there are more than one resource file with the same name:find <path-project-dir> -iname *<some-resource-name>*
Replace with actual resource from Xcode output.
We'll love contributions, fell free to fork and submit pull requests for additional generators or optimizations; for any question or idea write to team.mobile[AT]sysdata.it