19

I'd like to add multi-language support to a CocoaTouch Framework.

The problem: The Localizable.strings file I created only gets used by NSLocalizedString when it's part of the main app and its target. I'd like to store it inside the Framework to keep things separate.

How can I use the Localizable.strings when placed inside a CocoaTouch Framework?

Bernd
  • 11,133
  • 11
  • 65
  • 98

4 Answers4

15

Use:

NSLocalizedString("Good", tableName: nil, bundle: NSBundle(forClass: self), value: "", comment: "")

or you can create public func like this:

class func POLocalized(key: String) -> String{
    let s =  NSLocalizedString(key, tableName: nil, bundle: NSBundle(forClass: self.classForCoder()), value: "", comment: "")
    return s
}

example of use:

let locString = POLocalized("key")
yoAlex5
  • 29,217
  • 8
  • 193
  • 205
pbeo
  • 399
  • 1
  • 4
  • 14
  • 2
    Do not use NSBundle(forClass: self) for public classes, because some Main bundle classes can inherit framework class and NSBundle(forClass: self) will point to main bundle, not the framework. – Vladimir Koltunov Jul 13 '16 at 09:23
  • In this case u can use NSBundle(identifier: "FRAMEWORK_ID") – pbeo Jul 16 '16 at 10:55
  • What does the `value` parameter represent? The current Apple docs do not explain... – Nicolas Miari Oct 13 '16 at 09:01
  • It's a default value returned if the string is not found in the given table. – opyh May 18 '17 at 12:46
  • For those who might wonder: No matter how much localizations your framework may contain, they will not be returned by `NSLocalizedString` (with the solution above) if your project itself is not targeting the desired language also. – ixany Oct 20 '17 at 16:02
7

This can be done by specifying the bundle identifier of the framework in the NSLocalizedString constructor.

if let bundle: NSBundle = NSBundle(identifier: "com.mycompany.TheFramework") {
    let string = NSLocalizedString("key", tableName: nil, bundle: bundle, value: "", comment: "")
    print(string)
}
Kyle Clegg
  • 38,547
  • 26
  • 130
  • 141
4

You can add this struct to your codebase:

internal struct InternalConstants {
    private class EmptyClass {}
    static let bundle = Bundle(for: InternalConstants.EmptyClass.self)
}  

And then use optional bundle param to specify the location of your string file:

let yourString = NSLocalizedString("Hello", bundle: InternalConstants.bundle, comment: "")

Bundle.main is the default value if you don't use bundle param in your NSLocalizedString constructor.

Kirill
  • 738
  • 10
  • 26
  • 1
    Code only answers are discouraged. Please add some explanation as to how this solves the problem, or how this differs from the existing answers. [From Review](https://stackoverflow.com/review/low-quality-posts/22869358) – Nick Apr 28 '19 at 04:58
0

Get Localizable.strings from framework

A main point is to use Framework's bundle - bundle where strings(Localizable.string) are located

[Access to Framework bundle]

//e.g.
let someString = NSLocalizedString("some_string_id", tableName: nil, bundle: Bundle(identifier: "com.something")!, value: "", comment: "")

extension variant

extension String {
    public var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle(identifier: "com.something")!, value: "", comment: "")
    }
}

//using
let someString = "some_string_id".localized
yoAlex5
  • 29,217
  • 8
  • 193
  • 205