How to get localized Cancel, Done and etc?
Asked Answered
B

8

52

UIBarButtonItem have identifiers like Cancel, Done and some others. They are shown as text to user. If user changes language then for example Cancel button will be translated automatically. And as developer you do not need to provide localization string for this buttons. It means that Cancel, Done and other strings already localized and comes together with OS.

Is here a way to get this strings programmatically?

I do not want to add additional strings to localization files. And if it is possible to access then it would be very good.

Barogram answered 29/8, 2012 at 15:6 Comment(7)
can't you get access to your string through the title property?Decurved
I can get title of the UIBarButtonItem if this button is placed in UI. But I want to get this translations not using work around.Barogram
yourUIBarButtonItem.title let you retrieve the string that is displayed - is that what u want?Decurved
I know that I can get title of this button. As I wrote before Cancel, Done and other strings already comes together with OS with all localizations. What I want is to access this strings for OS.Barogram
@Decurved The question is valid: You might want to get the localized string without creating the button.Xiaoximena
@Ramis, did you find the way of getting these kinds of strings programmatically? Any success?Intersperse
@Stanislaw I did not find solution for it.Barogram
M
33

Here's a little macro I created to get the System UIKit Strings:

#define UIKitLocalizedString(key) [[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] localizedStringForKey:key value:@"" table:nil]

Use it like this:

UIKitLocalizedString(@"Search");
UIKitLocalizedString(@"Done");
UIKitLocalizedString(@"Cancel");
...
Motionless answered 25/4, 2014 at 20:3 Comment(4)
Is there any way to get all keys?Imply
I changed my tests to XCUI in Swift now and it doesn't work anymore :(Skippet
This no longer works, right? The UIKit bundle no longer has the Localized.string file. In fact, after searching through the runtime simulator files, I couldn't even identify where these strings are located at all.Belldame
No longer works because of the bundleWithIdentifier call. Swap it out for bundleForClass and it works again. See my answer for example.Motion
L
13

One (admittedly questionable) way of accomplishing this easily is use Apple's framework bundle localizations directly:

To see what they have to offer, open the following directory via the Finder:

/Applications/Xcode/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks

And in your case, you'll subsequently open ./UIKit.framework/English.lproj/Localizable.strings (in TextMate). Here you see a wide variety of translations that Apple uses for things like "Print", "OK", "On", "Off", etc. The real magic is that there are about 35 different language translations that you can copy into your own Localizable.strings files, for free.

If you are incredibly brazen and don't mind putting your app's future stability in question, you could skip the whole "copy into your own Localizable.strings" process and go straight to the source programmatically:

NSBundle *uiKitBundle = [NSBundle bundleWithIdentifier:@"com.apple.UIKit"];
NSString *onText = uiKitBundle ? [uiKitBundle localizedStringForKey:@"Yes" value:nil table:nil] : @"YES";
NSString *offText = uiKitBundle ? [uiKitBundle localizedStringForKey:@"No" value:nil table:nil] : @"NO";

Caveat: In no way do I recommend that you actually access these localized resources programmatically in an app that you intend to submit to the App Store. I'm merely illustrating a particular implementation that I've seen which addresses your original question.

Lymphatic answered 4/9, 2013 at 17:24 Comment(1)
Anyone know where these localized .strings files live now with Xcode 11? It seems like all the Frameworks paths inside the SDKs have only headers no strings files.Belldame
P
9

Encouraged by Answer to this Question (by Stephan Heilner) and Answer (by bdunagan) for iPhone/iOS: How can I get a list of localized strings in all the languages my app is localized in?

Objective-C

NSString * LocalizedString(NSString *key) {
    return [[NSBundle mainBundle] localizedStringForKey:key];
}

@interface NSBundle(Localization)
- (NSString *)localizedStringForKey:(NSString *)key;
- (NSDictionary<NSString *, NSString *> *)localizationTable;
@end

@implementation NSBundle(Localization)
- (NSDictionary<NSString *, NSString *> *)localizationTable {
    NSString *path = [self pathForResource:@"Localizable" ofType:@"strings"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSError *error = nil;
    id obj = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:&error];
    if (error && obj == nil) {
        @throw error;
        return nil;
    }
    if ([obj isKindOfClass:NSDictionary.class]) {
        return obj;
    }    
    @throw NSInternalInconsistencyException;
    return nil;
}

- (NSString *)localizedStringForKey:(NSString *)key {
    return [self localizedStringForKey:key value:nil table:nil];
}
@end

Swift 5

public extension String {
    func localized(_ bundle: Bundle = .main) -> String {
        bundle.localize(self)
    }        
    var localized: String {
        return localized()
    }
}

extension Bundle {
    static var UIKit: Bundle {
        Self(for: UIApplication.self)
    }
    func localize(_ key: String, table: String? = nil) -> String {
        self.localizedString(forKey: key, value: nil, table: nil)
    }
    var localizableStrings: [String: String]? {
        guard let fileURL = url(forResource: "Localizable", withExtension: "strings") else {
            return nil
        }
        do {
            let data = try Data(contentsOf: fileURL)
            let plist = try PropertyListSerialization.propertyList(from: data, format: .none)
            return plist as? [String: String]
        } catch {
            print(error)
        }
        return nil
    }
}

Usage:

"Photo Library".localized(.UIKit)

To get all keys of localized strings of UIKit:

Bundle.UIKit.localizableStrings?.keys//.map { $0 }
Pressure answered 15/3, 2018 at 14:45 Comment(0)
N
4

While perhaps not exactly what you were seeking, there is a commercial app in the Mac App Store called "System Strings" claiming that it provides a collection of more than 53000 standard localized strings. It was released November 2, 2012. I am in no way affiliated with this app or the author. The URL is https://itunes.apple.com/us/app/systemstrings/id570467776.

Nebulose answered 18/11, 2012 at 5:21 Comment(1)
Yes it is not what I wanted, but it looks good. Close to the point.Barogram
M
2

Working version in iOS 16. The earlier ones don't seem to work any longer

+(NSString*) uiKitLocalizedStringForKey:(NSString*)key {
    NSBundle* uikitBundle = [NSBundle bundleForClass:[UIButton class]];
    if (!uikitBundle) {
        // Never seen this happen, but might as well guard for it
        return key;
    }
    return [uikitBundle localizedStringForKey:key value:key table:nil];
}
Motion answered 11/5, 2023 at 14:49 Comment(0)
E
1

Sounds like what you are asking is if Apple provides a way to access a dictionary of pre-translated strings. I would think that anything provided by Apple for something like this would be located in their Docs: Internationalization Programming Topics

To answer your question I do not believe they provide a dictionary/list of known translations. Either you will have to define them in your Localizable.strings resource file or do as others have stated in the comments and pull the title from the UIBarButtonItem (I would go with the resource file personally).

Erivan answered 31/8, 2012 at 17:19 Comment(0)
G
0

Why not use base localization with your storyboard? It will localize it for you.

Gonzalogoo answered 1/4, 2014 at 15:7 Comment(1)
I needed access to these for some KIF integration tests.Motionless
U
-6

You could use

NSLocalizedString(@"Cancel", @"Cancel")
Unshod answered 3/4, 2014 at 9:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.