Series 6— Custom operators combined with localization
In this episode we are gonna use custom operator for setting localizable strings on UI components.
Note: This is just a simple example, not a real world solution.
This episode’s goal:
let label = UILabel() <- Localization.welcomeMessage
print(label.text?) // prints "Gimme some sugar."
Let’s declare Localizable
protocol responsible for providing localized string:
protocol Localizable {
var localizedString: String? { get }
}
Our localization is enum
type. Each of its case represents a key which will be used in NSLocalizedString
macro.
enum Localization: String, Localizable {
case welcomeMessage = "Gimme some sugar."
case warningMessage = "Too much sugar!"
}
Localization enum
is RawRepresentable
with String
as its associated type so this knowledge can be used in our default implementation of Localizable
protocol.
extension Localizable
where Self: RawRepresentable, Self.RawValue == String
{
var localizedString: String? {
return NSLocalizedString(rawValue, comment: "")
}
}
Custom operator
We’re gonna use infix
operator. Custom operators are not covered in this post. Read more about custom operators.
infix operator <-: AdditionPrecedence
Protocol which will provide abstraction for any object which has text: String?
property. We’ll call it TextAware
:
protocol TextAware: class {
var text: String? { get set }
}
Apply <-
operator to TextAware
protocol:
extension TextAware {
static func <-(left: Self, right: Localization) -> Self {
left.text = right.localizedString
return left
}
}
Now we can extend UI components with TextAware
:
extension UILabel: TextAware {}
extension UITextField: TextAware {}
And finally we can use:
let label = UILabel() <- Localization.welcomeMessage
print(label.text?) // prints "Gimme some sugar."let textField = UITextField() <- Localization.warningMessage
print(textField.text?) // prints "Too much sugar!"
Pretty easy, isn’t it?