Objective-C helper classes for Apple iOS strings
The Respresso generates Objective-C helper classes, so you can reference localizations from Objective-C source code in a typo-safe way with auto-completion support in Xcode. For this, Respresso generates 2 helper classes:
RespressoStringKeys
: Contains all localizations keys as readonly properties.RespressoLanguages
: Contains all localization languages as readonly properties. It also provides a getter property fordefaultLanguage
and thelanguages
array.RespressoStrings
: Contains a readonly property for each localization key that returns locale specific translation. In case the key has localization variables, a function will be generated with them as arguments. It also provides language switching capabilities for localizations accessed through this class.
This format can't be imported to Respresso, it's output only.
How Respresso generates it?
This format is language independent, thus you will get the same files regardless of the added languages.
You can expect to get the following files:
RespressoStringKeys.h
RespressoStringKeys.m
RespressoLanguages.h
RespressoLanguages.m
RespressoStrings.h
RespressoStrings.m
Let's assume you have a single localization with two registered variables in Respresso:
mainScreen.accountBalance
:
- English (en):
Balance: {{ currency }} {{ balance }}
- English (en-GB): Unspecified
- Hungarian (hu):
Egyenleg: {{ balance }} {{ currency }}
It will output 6 files like these in the objc
sync group:
#import <Foundation/Foundation.h>
@interface RespressoStringKeys : NSObject
- (nonnull instancetype)init NS_UNAVAILABLE;
@property(class, nonnull, nonatomic, readonly) NSString* mainScreenAccountBalance;
@end
#import "RespressoStringKeys.h"
@implementation RespressoStringKeys
+ (nonnull NSString*)mainScreenAccountBalance {
return @"mainScreen.accountBalance";
}
@end
#import <Foundation/Foundation.h>
@interface RespressoLanguages : NSObject
- (nonnull instancetype)init NS_UNAVAILABLE;
@property(class, nonnull, nonatomic, readonly) NSString* en;
@property(class, nonnull, nonatomic, readonly) NSString* enGB;
@property(class, nonnull, nonatomic, readonly) NSString* hu;
@property(class, nonnull, nonatomic, readonly) NSString* defaultLanguage;
@property(class, nonnull, nonatomic, readonly) NSArray* languages;
@end
#import "RespressoLanguages.h"
@implementation RespressoLanguages
+ (nonnull NSString*)en { return @"en"; }
+ (nonnull NSString*)enGB { return @"en-GB"; }
+ (nonnull NSString*)hu { return @"hu"; }
+ (nonnull NSString*)defaultLanguage { return @"en"; }
+ (nonnull NSArray*)languages {
return @[@"en", @"en-GB", @"hu"];
}
@end
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface RespressoStrings : NSObject
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nullable NSString *)localizedStringWithKey:(nullable NSString *)key;
@property (class, nullable, nonatomic) NSString* language;
@property(class, nonnull, nonatomic, readonly) NSString* mainScreenAccountBalance;
+ (nonnull NSString*)mainScreenAccountBalanceCurrency:(nonnull NSString*)currency balance:(CGFloat)balance;
@end
#import "RespressoStrings.h"
// There will be an internal interface not shown here
@implementation RespressoStrings
// There will be some internal functions not shown here
// Force a specific language to be used when accessed localizations through RespressoStrings
+ (void)setLanguage:(nullable NSString *)language { /* implementation */ }
+ (NSString*)language { /* implementation */ }
// Dynamically access localizations
// Calls NSLocalizedString(...) with RespressoStrings.language specific bundle
+ (nullable NSString*)localizedStringWithKey:(nullable NSString *)key { /* implementation */ }
+ (nonnull NSString*)mainScreenAccountBalance {
return [RespressoStrings localizedStringWithKey:@"mainScreen.accountBalance"];
}
+ (nonnull NSString*)mainScreenAccountBalanceCurrency:(nonnull NSString*)currency balance:(CGFloat)balance {
return [NSString stringWithFormat: [RespressoStrings mainScreenAccountBalance], currency, balance];
}
@end
Usage
Respresso's localization helper classes brings typo safe support to access localizations form code, even with parameters. You can easily force a specific language instead of the system default.
Access localized text
Each time you want to use a localized text from Respresso, you should access it through the RespressoStrings
class. This is no magic, it uses the
standard NSLocalizedString(...)
and String(format: ...)
but you will get auto-completion support in Xcode to boost your productivity. This will
guarantee that the key is always matching the key in the .strings file, there is no more place for typos or missing localizations. For localizations
with variables, you will also get a function with the proper parameter list with the proper types based on variable formatting set in Respresso.
How to access localizations:
#import "RespressoStrings.h"
NSString* localized = RespressoStrings.mainScreenAccountBalance;
// localized = "Balance: %1$@ %2$.2f" on English devices
NSString* formattedWithParams = [RespressoStrings mainScreenAccountBalanceCurrency:@"USD" balance: 143.1268];
// formattedWithParams = "Balance: USD 143.13" on English devices
NSString* dynamicKey = [RespressoStrings localizedStringWithKey:@"mainScreen.accountBalance"];
// dynamicKey = "Balance: %1$@ %2$.2f" on English devices - same as localized
Force a specific language
Many apps provide language settings within the app that is a tedious task to implement in iOS as language switching is not available. Thus, we decided
to bring you that feature out of the box if you use these helper classes to access localizations. For this, you get the RespressoLanguages
class
with the defaultLanguage
and languages
properties.
Switch language:
#import "RespressoStrings.h"
#import "RespressoLanguages.h"
RespressoStrings.language = RespressoLanguages.hu; // Force Hungarian language
NSString* localized = RespressoStrings.mainScreenAccountBalance; // "Egyenleg: %2$.2f %1$@"
RespressoStrings.language = nil; // Return to system default language (English)
localized = RespressoStrings.mainScreenAccountBalance; // "Balance: %1$@ %2$.2f"
Available languages:
To build a dynamic language selector, you will need to iterate over all the languages, therefore the RespressoLanguages
class has a languages
array. In addition to this, it provides the defaultLanguage
property that will contain the language code that corresponds to the language marked as
default in Respresso. Let's see an example:
#import "RespressoLanguages.h"
NSArrray* languages = RespressoLanguages.languages;
// languages = ["en", "en-GB", "hu"]
NSString* defaultLanguage = RespressoLanguages.defaultLanguage;
// defaultLanguage = "en"
Access localization keys
If you want to access the localization key that is present in the RespressoStrings.strings
files, you have to use the RespressoStringKeys
class:
#import "RespressoStringKeys.h"
NSString* key = RespressoStringKeys.mainScreenAccountBalance;
// key = "mainScreen.accountBalance"
This can be used to access localizations using the standard NSLocalizedString(key, ...)
or to look up localizations from a dynamically downloaded
json from your backend.
Migration from legacy (v1) class
When we introduced the new Respresso CLI, this format also changed. We have a migration guide to help you transition to the new CLI and the new format.
Open migration guide