genstrings chokes when using the value parameter in Swift
Asked Answered
F

2

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?

Fornax answered 14/8, 2015 at 19:56 Comment(1)
For a genstrings replacement that actually works and isn't dead slow, check out github.com/kayak/SwiftGenStrings.Fornax
M
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. ...

Madisonmadlen answered 14/8, 2015 at 20:16 Comment(4)
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!Fornax
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) :-/Abstemious
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.Excrescency
FWIW, I tried the code in the question with Xcode 14 and it worked...Loupe
R
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”;
Rochellerochemont answered 1/7, 2016 at 11:6 Comment(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.Fornax
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.Fornax
Thanks Cliff, the second command with extractLocStrings worked for me in Xcode 7.3.1 with my Swift files.Pietrek
M
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. ...

Madisonmadlen answered 14/8, 2015 at 20:16 Comment(4)
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!Fornax
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) :-/Abstemious
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.Excrescency
FWIW, I tried the code in the question with Xcode 14 and it worked...Loupe

© 2022 - 2024 — McMap. All rights reserved.