14

I have a basic Swift file Test.swift which contains

import Foundation
import UIKit

class Test: NSObject {
    let a: String
    let b: String

    override init() {
        a = NSLocalizedString("key 1", tableName: nil,
            bundle: NSBundle.mainBundle(), value: "value 1", comment: "comment 1")
        b = NSLocalizedString("key 2", comment: "comment 2")
    }
}

When I run genstrings on this file I receive an unexpected warning

$ genstrings -u Test.swift
Bad entry in file Test.swift (line = 9): Argument is not a literal string.

and the generated Localizable.strings file is missing the entry for "key 1"

$ cat Localizable.strings 
??/* comment 2 */
"key 2" = "key 2";

However, when I do the equivalent in Objective-C using the below code in a file Test.m

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Test: NSObject

@property (nonatomic, strong) NSString *a;
@property (nonatomic, strong) NSString *b;

@end

@implementation Test

- (id)init {
    self = [super init];
    if (self) {
        self.a = NSLocalizedStringWithDefaultValue(@"key 1", nil, [NSBundle mainBundle], @"value 1", @"comment 1");
        self.b = NSLocalizedString(@"key 2", @"comment 2");
    }
    return self;
}

@end

the genstrings command works as expected and I get the entry for "key 1".

$ genstrings -u Test.m 
$ cat Localizable.strings 
??/* comment 1 */
"key 1" = "value 1";

/* comment 2 */
"key 2" = "key 2";

What am I doing wrong?

hennes
  • 9,147
  • 4
  • 43
  • 63
  • For a `genstrings` replacement that actually works and isn't dead slow, check out https://github.com/kayak/SwiftGenStrings. – hennes Nov 24 '16 at 19:27

2 Answers2

30

Apparently Apple has stepped away from supporting genstrings. Instead use:

xcrun extractLocStrings

as your command. For example, to create Localizable.strings for your project:

find ./ -name "*.m" -print0 | xargs -0 xcrun extractLocStrings -o en.lproj

and for Swift:

find ./ -name "*.swift" -print0 | xargs -0 xcrun extractLocStrings -o en.lproj

Note that if you are going to export to a .xliff file there is no longer any need to run genstrings at all as the xCode

Editor > Export for localization

command will process your strings 'behind the scenes'.

Update: I’m on xCode 7.3.1 and on my system xtractLocStrings is a binary.

$ file /Applications/Xcode.app//Contents/Developer/usr/bin/extractLocStrings
    /Applications/Xcode.app//Contents/Developer/usr/bin/extractLocStrings: Mach-O 64-bit executable x86_64

Here is my test:

let _ = NSLocalizedString("1st", comment: "1st string")
let _ = NSLocalizedString("Second", tableName: "Localized", bundle: NSBundle.mainBundle(), value: "2nd", comment: "2nd string”)

and here are the results:

Localizable.strings:
/* 1st string */
"1st" = "1st”;

Localized.strings:
/* 2nd string */
"Second" = "2nd”;
Spiff
  • 783
  • 8
  • 9
  • 3
    That doesn't seem to solve the problem. I get the exact same error message. The help output of `extractLocStrings` also indicates that it's nothing but a wrapper around `genstrings`. – hennes Jul 04 '16 at 07:18
  • When I run it on the test code you provided, I get an index-out-of-bounds exception in extractLocStrings here. When I run it on the code sample in my question, I get the same error reported by genstrings and the strings file only contains one string. Is there any way to check what version of extractLocStrings/genstrings both of us are running? I'm surprised to see a difference to be honest. – hennes Jul 07 '16 at 19:26
  • 1
    Thanks Cliff, the second command with extractLocStrings worked for me in Xcode 7.3.1 with my Swift files. – Joshua Finch Jul 25 '16 at 09:36
15

This is a bug of genstrings in both Xcode 6.4 and Xcode 7 beta, as reported in https://openradar.appspot.com/22133811:

In Swift files, genstrings Chokes On NSLocalizedString calls with more than two parameters

Summary: When running genstrings against a Swift file, if there are any NSLocalizedString calls that use more than the trivial case of "value" and "comment" parameters, genstrings errors out. ...

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • I spent ages searching for this issue on the web but couldn't find anything useful and then it turns out there is a radar that uses almost the same wording. Maybe I used the wrong search engine. :D Thanks! – hennes Aug 15 '15 at 06:42
  • I have just created a radar for this as well... Hope this will be fixed but right now I have to find some ugly workaround (loading the localized strings from an ObjC File) :-/ – MeXx Sep 23 '15 at 09:38
  • 3
    this is a bug of Xcode 6, Xcode 7, Xcode 8 and will never be solved by Apple. They had enough time to do that and don't care. – Duck Sep 22 '16 at 12:28
  • FWIW, I tried the code in the question with Xcode 14 and it worked... – mokagio Nov 19 '22 at 05:08