Issue with genstrings for Swift file
Asked Answered
D

7

25

genstrings works well to extract localizable content from .m file as,

find . -name \*.m | xargs genstrings -o en.lproj

But, not working for .swift file as,

find . -name \*.swift | xargs genstrings -o en.lproj
Diuretic answered 13/10, 2014 at 13:3 Comment(0)
D
36

The genstrings tool works fine with swift as far as I am concerned. Here is my test:

// MyClass.swift
let message = NSLocalizedString("This is the test message.", comment: "Test")

then, in the folder with the class

# generate strings for all swift files (even in nested directories)
$ find . -name \*.swift | xargs genstrings -o .

# See results
$ cat Localizable.strings
/* Test */
"This is the test message." = "This is the test message.";
$
Drawback answered 13/10, 2014 at 13:15 Comment(6)
I see, genstrings tracks NSLocalizedString, but I have used string extension like localizedString(). So my string becomes "This is the test message.".localizedString() and that's why it is not being trackedDiuretic
Well, you know what to do. Your problem can be solved with one smart global text replace operation. Start by ticking the checkmark above ;-).Drawback
note: genstrings does not work for any long-form (arguably best practice) usage: NSLocalizedString("checkout-okbtn", value: "Ok", comment: "in cart checkout, the button that pays") radar issueCookhouse
I also (just) found out that genstrings does not work correctly with my Swift files in a mixed Objective-C/Swift project! I am most definitely using NSLocalizedString with string literals only. For example, this message is not found: localizedName = NSLocalizedString("Popular Now", comment: "Name of the menu item to select content that is popular now") -- This is a really big deal. I must find a solution for this a.s.a.p. I'll be looking into philipp's recommendation to try out github.com/KeepSafe/genstrings_swiftEmptyhanded
Wait, I just realize why. I'm running a genstrings command where I'm only looking for *.m files. Let me see if I can alter that to find both *.m and *.swift in one go...Emptyhanded
Yes, working fine for both Objective-C and Swift in my mixed project now I changed the command to the following: cd ~/Workspace/ios-ecentral-app/ECentral/;find ./ -type f \( -iname \*.m -o -iname \*.swift \) | xargs genstrings -o ECentral/localization/en.lproj/'Emptyhanded
C
5

I believe genstrings works as intended, however Apple's xargs approach to generate strings from all your project's files is flawed and does not properly parse paths containing spaces.

That might be the reason why it's not working for you.

Try using the following:

find . -name \*.swift | tr '\n' '\0' | xargs -0 genstrings -o .

Cnut answered 11/3, 2018 at 0:32 Comment(2)
This solved my problem with some declarations that included newline. Thank you!Bodyguard
find . -name \*.swift -print0 | xargs -0 genstrings -o ., no need for replacing anything with tr.Providential
S
4

We wrote a command line tool that works for Swift files and merges the result of apples genstrings tool. It allows for key and value in NSLocalizedString

https://github.com/KeepSafe/genstrings_swift

Sodium answered 6/4, 2015 at 16:14 Comment(4)
philipp, I have a project that is a mix of Objective-C and Swift. I have found that the genstrings tool only finds the message from the Objective-C source code. This genstrings_swift tool, can it be run on a mixed-code project like mine and find all the messages in one go, or do I need to follow a sequence of steps?Emptyhanded
This is the genstrings command I am using now, by the way: cd ~/Workspace/ios-ecentral-app/ECentral/;find . -name \*.m | xargs genstrings -o ECentral/localization/en.lproj/Emptyhanded
Oh wait... doh! I should edit that command to include *.swift...!Emptyhanded
Okay, fixed by changing my alias to the following: alias genstringsECentral='cd ~/Workspace/ios-ecentral-app/ECentral/;find ./ -type f \( -iname \*.m -o -iname \*.swift \) | xargs genstrings -o ECentral/localization/en.lproj/' -- works like a charm now.Emptyhanded
D
2

There's an alternative tool called SwiftGenStrings

Hello.swift

NSLocalizedString("hello", value: "world", comment: "Hi!")

SwiftGenStrings:

$ SwiftGenStrings Hello.swift 

/* Hi! */
"hello" = "world";

Apple genstrings:

$ genstrings Hello.swift

Bad entry in file Hello.swift (line = 1): Argument is not a literal string.

Disclaimer: I worked on SwiftGenStrings.

Decameter answered 8/2, 2018 at 13:34 Comment(0)
S
0

There is a similar question here: How to use genstrings across multiple directories?

find ./ -name "*.m" -print0 | xargs -0 genstrings -o en.lproj
Semiology answered 29/4, 2019 at 11:52 Comment(0)
P
0

The issue I was having with find/genstrings was twofold:

  1. When it reached folder names with spaces (generated by the output of find), it would exit with an error
  2. When it reached the file where I had my custom routine defined, it was giving me an error when trying to parse my actual function definition

To fix both those problems I'm using the following:

find Some/Path/ \( -name "*.swift" ! -name "MyExcludedFile.swift" \) | sed "s/^/'/;s/$/'/" | xargs genstrings -o . -s MyCustomLocalizedStringRoutine

To summarize, we use the find command to both find and exclude your Swift files, then pipe the results into the sed command which will wrap each file path in quotes, then finally pipe that result into the genstrings command

Pale answered 9/1, 2020 at 17:10 Comment(0)
B
0

Xcode now includes a powerful tool for extracting localizations.

Just select your project on the left then Editor menu >> Export localizations.

You'll get a folder with all the text in your files as well as the Localizable.strings and InfoPlist.strings

More details here: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html

Bronez answered 11/3, 2020 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.