A tool for finding missing and unused NSLocalizedStrings

Overview

nslocalizer

Code Climate Test Coverage CircleCI branch Dependency Status

This is a command line tool that is used for discovering missing and unused localization strings in Xcode projects.

Contributing and Code of Conduct License

This project and related material has a Code of Conduct that is listed in the contributing.md file. This must be read and adhered to when interacting with this project. Additionally this code is released under a 3-clause BSD license that you can read here.

Requirements Python

This tool is built and tested against Python 3.5.0.

Module Version
pbPlist >=1.0
pyobjc-core >= 2.5.1
pyobjc-framework-Cocoa >= 2.5.1
langcodes >= 1.2.0

Installation

Via pip and python 3

$ pip3 install nslocalizer

To install the tool from the repo, clone from Github then run the make build command.

Usage

To use nslocalizer to generate warnings about missing or unused NSLocalizedStrings, you will have to pass it a project and target as input:

$ nslocalizer --project <path to xcodeproj file> --target <names of targets to analyze>

There are a number of flags that can be passed to modify the behavior of pyconfig:

Flags Usage
--version Displays the version of nslocalizer and exits
--find-missing Finds any strings that are missing translations for any of the supported languages
--find-unused Finds any strings that are unused in the code
--quiet Silences all logging output
--verbose Logs additional information
--ignore <languages> Will silence warnings for any of the languages listed to be ignored

Note: Both --find-missing and --find-unused flags can be supplied to the same invocation of nslocalizer.

Example

Find missing translation strings:

$ nslocalizer --project Foo.xcodeproj --target MyNewApp --find-missing
/Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:327: warning: String "foo_setup_twitter_integation" missing for: German, Traditional Chinese, European Portuguese, Spanish
/Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:356: warning: String "foo_setup_facebook_integation" missing for: German, Traditional Chinese, European Portuguese, Swedish, Polish, Latin American Spanish, British English, Brazilian Portuguese

Find unused translation strings:

$ nslocalizer --project Foo.xcodeproj --target MyNewApp --find-unused
/Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:327: warning: String "foo_setup_twitter_integation" is not used
/Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:356: warning: String "foo_setup_facebook_integation" is not used

Integration

nslocalizer is intended to be used as part of a build of the Xcode project file. To integrate you will have to add a new "run script" phase to your target and then invoke as such:

nslocalizer --project $PROJECT_DIR/YourProject.xcodeproj --target $TARGET_NAME --find-missing --find-unused
Comments
  • unable to successfully install and run nslocalizer

    unable to successfully install and run nslocalizer

    Type of issue: Bug


    Related Files: https://gist.github.com/c859ec7ca61130369fc40bea3b53b9a8


    Description: Followed all install instructions, but am getting "command not found" when running nslocalizer. Install seems to fail on install_requirements.txt, after which it prints: If reporting this issue please do so at (not Homebrew/brew or Homebrew/core): https://github.com/samdmarshall/homebrew-formulae/issues

    I followed all brew/Troubleshooting instructions, updated my XCode command line tools, restarted everything... no effect. I have also tried installing python3, but it says it's already installed.


    opened by tymrtn 9
  • Failure running `brew install` on macOS 10.14.3

    Failure running `brew install` on macOS 10.14.3

    Bug: Permission failures on brew install due to system protections present on macOS 10.13+


    Description:

    When I try to install via brew install, I get the following errors:

    $ brew install samdmarshall/formulae/nslocalizer
    ==> Installing nslocalizer from samdmarshall/formulae
    ==> Cloning https://github.com/samdmarshall/nslocalizer.git
    Updating /Users/bjhomer/Library/Caches/Homebrew/nslocalizer--git
    ==> Checking out branch develop
    Already on 'develop'
    Your branch is up to date with 'origin/develop'.
    HEAD is now at 4c00aa1 Merge pull request #10 from samdmarshall/updating-pbPlist-version
    Entering 'docs'
    /Users/bjhomer/Library/Caches/Homebrew/nslocalizer--git/docs
    ==> pip3 install -r install_requirements.txt
    Last 15 lines from /Users/bjhomer/Library/Logs/Homebrew/nslocalizer/01.pip3:
      Building wheel for pbPlist (setup.py): finished with status 'done'
      Stored in directory: /private/tmp/nslocalizer-20190225-22020-mnpzab/.brew_home/Library/Caches/pip/wheels/7a/8e/c5/1222a694fb77543c4a19a9a783ce962abd63f0ad3eff749cb9
      Building wheel for langcodes (setup.py): started
      Building wheel for langcodes (setup.py): finished with status 'done'
      Stored in directory: /private/tmp/nslocalizer-20190225-22020-mnpzab/.brew_home/Library/Caches/pip/wheels/84/20/3d/dc2010b4f7c0b786a06947530a962972caead0c58898f25a02
      Building wheel for biplist (setup.py): started
      Building wheel for biplist (setup.py): finished with status 'done'
      Stored in directory: /private/tmp/nslocalizer-20190225-22020-mnpzab/.brew_home/Library/Caches/pip/wheels/e1/a5/ce/28ba6a80c2487f54deec4a2eda7ccda8bcbeeec2aad39e9779
      Building wheel for marisa-trie (setup.py): started
      Building wheel for marisa-trie (setup.py): finished with status 'done'
      Stored in directory: /private/tmp/nslocalizer-20190225-22020-mnpzab/.brew_home/Library/Caches/pip/wheels/45/24/79/022624fc914f0e559fe8a1141aaff1f9df810905a13fc75d57
    Successfully built pbPlist langcodes biplist marisa-trie
    Installing collected packages: pyobjc-core, pyobjc-framework-Cocoa, biplist, pbPlist, marisa-trie, langcodes
    Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/usr/local/lib/python3.7/site-packages/pyobjc_core-5.1.2-py3.7-nspkg.pth'
    
    
    If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):
    https://github.com/samdmarshall/homebrew-formulae/issues
    

    It appears that /usr/local/lib/python3.7 is protected when running brew install for some reason, and it's causing problems with the pip3 install command in the nslocalizer brew formula. I've checked that the permissions on the directory are correct, but installation still fails. I was able to get around it by manually running pip3 install pyobjc-core, pyobjc-framework-Cocoa, biplist, pbPlist, marisa-trie, langcodes, but most users won't know to do that. And even after doing that, I had trouble when trying to update to a newer version of nslocalizer.

    This is likely the same cause behind issue #7.

    A possible solution is to pass the --user flag to pip3 install. When I modified the home-brew formula to pass that flag, installation succeeded and the issues were resolved. Passing --user does limit the functionality to the current user, but that seems to mostly be the default behavior of homebrew anyway, so that's probably fine?

    opened by bjhomer 8
  • Exception while trying to find missing strings

    Exception while trying to find missing strings

    My xcodeproj is part of a xcworkspace (which has multiple xcodeproj), not sure if this error is related to that?

    Type of issue: [ Bug ]


    Related Files:


    Description:

    $ nslocalizer --project <MY_PROJECT>.xcodeproj --target <MY_TARGET> --find-missing
    Traceback (most recent call last):
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/Switch.py", line 41, in __iter__
        raise StopIteration # pragma: no cover
    StopIteration
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/usr/local/bin/nslocalizer", line 11, in <module>
        load_entry_point('nslocalizer==1.0.1', 'console_scripts', 'nslocalizer')()
      File "/usr/local/lib/python3.7/site-packages/nslocalizer-1.0.1-py3.7.egg/nslocalizer/main.py", line 123, in main
        Executor.run(args)
      File "/usr/local/lib/python3.7/site-packages/nslocalizer-1.0.1-py3.7.egg/nslocalizer/Executor/Executor.py", line 58, in run
        xcodeproj_file = xcodeproj(project_file_path)
      File "/usr/local/lib/python3.7/site-packages/nslocalizer-1.0.1-py3.7.egg/nslocalizer/xcodeproj/xcodeproj.py", line 44, in __init__
        self.project_file = pbProj.PBXProj(pbxproj_file_path)
      File "/usr/local/lib/python3.7/site-packages/nslocalizer-1.0.1-py3.7.egg/nslocalizer/xcodeproj/pbProj/pbProj.py", line 38, in __init__
        plist = pbPlist.pbPlist.PBPlist(file_path)
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbPlist.py", line 41, in __init__
        self.root = parser.read()
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 118, in read
        parsed_plist = self.__readTest(True)
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 133, in __readTest
        read_result = self.__parse(requires_object)
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 142, in __parse
        parsed_item = pbItem.pbItemResolver(self.__parseDict(), 'dictionary') # pylint: disable=redefined-variable-type
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 256, in __parseDict
        new_object = self.__readTest(False)
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 133, in __readTest
        read_result = self.__parse(requires_object)
      File "/usr/local/lib/python3.7/site-packages/pbPlist-1.0.3-py3.7.egg/pbPlist/pbParser.py", line 139, in __parse
        for case in Switch(starting_character):
    RuntimeError: generator raised StopIteration
    
    opened by ApoorvKhatreja 5
  • ignore language option does not take effect

    ignore language option does not take effect

    Type of issue: [ Bug ]


    Description: When using the --ignore <language> option, the language selected to ignore is still listed in the results

    Standard --find-missing

    ➜  imu git:(master) nslocalizer --project Qrof.xcodeproj --target Qrof --find-missing
    Base.lproj/Localizable.strings:24: warning: String "lbl_verify_email_1" missing for: Spanish, Korean, Traditional Chinese, Italian, French, German, Simplified Chinese
    

    With --ignore option

    ➜  imu git:(master) nslocalizer --project Qrof.xcodeproj --target Qrof --ignore French --find-missing
    Base.lproj/Localizable.strings:24: warning: String "lbl_verify_email_1" missing for: Italian, French, Simplified Chinese, German, Spanish, Korean, Traditional Chinese
    
    enhancement 
    opened by jinjorge 4
  • AttributeError: 'dict' object has no attribute 'resolvePath'

    AttributeError: 'dict' object has no attribute 'resolvePath'

    Type of issue: [ Bug ]


    Related Files:

    None


    Description:

    Hi! First of all I must say nslocalizer looks like a great tool. Thank you for open-sourcing it! I've installed nslocalizer according to Installation section of readme and I'm using it this way nslocalizer --project Inbbbox.xcodeproj/ --target Inbbbox --find-unused. Unfortunately, it's not working for me, please see crash report. Project I'm trying to check is open-sourced so you can check it for yourself (https://github.com/netguru/inbbbox-ios) Let me know if you need more informations, happy to help to debug this issue.


    Crash Report:

    Summary Goes Here
    Traceback (most recent call last):
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/bin/nslocalizer", line 9, in <module>
        load_entry_point('nslocalizer==1.0', 'console_scripts', 'nslocalizer')()
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/main.py", line 117, in main
        Executor.run(args)
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/Executor/Executor.py", line 75, in run
        unused_strings = cls.findUnusedStrings(xcodeproj_file, desired_targets)
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/Executor/Executor.py", line 98, in findUnusedStrings
        code_files.extend(CodeFinder.getCodeFileList(project.project_file, target))
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/Finder/CodeFinder.py", line 45, in getCodeFileList
        all_file_refs = [PathFinder.resolveFilePathForReference(project, build_file.store[pbProj.PBX_Constants.kPBX_BUILDFILE_fileRef]) for build_file in all_build_files]
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/Finder/CodeFinder.py", line 45, in <listcomp>
        all_file_refs = [PathFinder.resolveFilePathForReference(project, build_file.store[pbProj.PBX_Constants.kPBX_BUILDFILE_fileRef]) for build_file in all_build_files]
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/Finder/PathFinder.py", line 34, in resolveFilePathForReference
        file_path = reference.resolvePath(project)
      File "/usr/local/Cellar/nslocalizer/1.0/libexec/lib/python3.5/site-packages/nslocalizer/xcodeproj/pbProj/PBXItem.py", line 77, in __getattr__
        return getattr(self.store, attrib)
    AttributeError: 'dict' object has no attribute 'resolvePath'
    

    opened by pikor 2
  • installation through homebrew fails

    installation through homebrew fails

    Description: brew tap sandmarshall/formulae fails since it can't find the associated github repo

    Cloning into '/usr/local/Homebrew/Library/Taps/sandmarshall/homebrew-formulae'...
    remote: Repository not found.
    fatal: repository 'https://github.com/sandmarshall/homebrew-formulae/' not found
    Error: Failure while executing; `git clone https://github.com/sandmarshall/homebrew-formulae /usr/local/Homebrew/Library/Taps/sandmarshall/homebrew-formulae --depth=1` exited with 128.
    
    

    opened by sgbasaraner 1
  • linting and updating dangerfile

    linting and updating dangerfile

    Title: fixing the code to conform to linting rules


    Description: this is a pass at cleaning up the code to conform to the linting rules so i can work with it easier when i start work on this project.

    opened by samdmarshall 1
  • take strings set via IBlocalizable into account

    take strings set via IBlocalizable into account

    Type of issue: Request


    Description:

    I am using this lib : https://github.com/PiXeL16/IBLocalizable which allow localization from storyboard.

    When I use nslocalizer "--find-unused" all string set via IBLocalizable in storyboard are considered as unused. Is it possible to take IBlocalizable into account ?


    opened by gregoireLem 1
Releases(v1.0.1)
  • v1.0.1(Dec 19, 2016)

    changes that address issues with loading some files with BOM correctly. Also fixes when non-source files are included in the compile sources build phase.

    Source code(tar.gz)
    Source code(zip)
  • v1.0(Sep 3, 2016)

    Initial release of nslocalizer, a tool that will warn when you have missing or unused NSLocalizedStrings in your Xcode project file.

    Installation Instructions:

    $ brew update
    $ brew tap samdmarshall/formulae
    $ brew install samdmarshall/formulae/nslocalizer
    
    Source code(tar.gz)
    Source code(zip)
Owner
Samantha Demi
Samantha Demi
transai is a localization tool on Android and iOS.

transai transai is a command line tool to help you do Android and iOS translation management. You can extract string files to csv format, or generate

Jintin 56 Nov 12, 2022
A CLI tool for localization resource management on Xcode. Built with Google Translator.

Supported by Jetbrains Open Source License Program Automatically translate and synchronize '.strings' files from the defined base language The basic c

gitmerge 164 May 4, 2022
Will Powell 1.2k Dec 29, 2022
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
Localize is a framework writed in swift to localize your projects easier improves i18n, including storyboards and strings.

Localize Localize is a framework written in swift to help you localize and pluralize your projects. It supports both storyboards and strings. Features

Andres Silva 279 Dec 24, 2022
Swift friendly localization and i18n with in-app language switching

Localize-Swift Localize-Swift is a simple framework that improves i18n and localization in Swift iOS apps - providing cleaner syntax and in-app langua

Roy Marmelstein 2.9k Dec 29, 2022
NoOptionalInterpolation gets rid of "Optional(...)" and "nil" in Swift's string interpolation

NoOptionalInterpolation gets rid of "Optional(...)" and "nil" in Swift's string interpolation

Thanh Pham 48 Jun 5, 2022
Semi-automated Text Translator for Websites and Apps

macOS/Ubuntu/Windows: attranslate is a semi-automated tool for "synchronizing" translation-files. attranslate is optimized for fast and smooth rollout

Felix Kirchengast 272 Dec 21, 2022
How to use swiftlint to identify unused code or unused imports in a Swift codebase

Swift compilation database This repository demonstrates how to use swiftlint to identify unused code or unused imports in a Swift codebase. How to run

Andrés Cecilia Luque 3 Aug 26, 2022
🚗 iOS app for finding public parking lots

?? ParkenDD ParkenDD shows you the current parking situation for various European cities, including Dresden, Ingolstadt, Hamburg, Zürich and Aarhus to

Kilian Koeltzsch 49 Feb 9, 2022
iOS application for finding formants in spoken sounds

FORMANT PLOTTER Buy on the App Store: https://itunes.apple.com/us/app/formant-analyzer/id799183655?mt=8&uo=4&at=11l6hc&ct=fnd This is an iOS project t

William Entriken 51 Dec 25, 2022
Wordle-solver - A little command line app for finding the answer to Wordle

A little command line app for finding the answer to Wordle puzzles, written in S

Dalton Claybrook 6 Nov 2, 2022
Command line program that detects unused resource strings in an iOS or OS X application.

Abandoned Resource String Detection This command line program detects unused resource strings in an iOS or OS X application. Updated to Swift 3, thank

Josh Smith 360 Nov 26, 2022
🌊 A clean wave - report unused localized strings

Ripple ?? Ripple - a command line tool that reports unused localization strings in your Xcode project. Install Clone from repo git clone cd Ripple sw

Edoardo Benissimo 3 Sep 16, 2022
A phantom type is a custom type that has one or more unused type parameters.

PhantomTypes A phantom type is a custom type that has one or more unused type parameters. Phantom types allow you to enforce type-safety without sacri

null 3 Nov 4, 2022
DevTool - A simple UI and powerful Mac OS application, Such as JSON-Formatting tool, JSON-to-model tool, AppIcon generator, Network-Request tool...

?? ?? ?? A simple UI and powerful Mac OS application. It is a collection of tools commonly used in my development work. Such as JSON-Formatting tool, JSON-to-model tool, AppIcon generator, Network-Request tool...

渠晓友 3 Dec 21, 2022
Makes it easier to support older versions of iOS by fixing things and adding missing methods

PSTModernizer PSTModernizer carefully applies patches to UIKit and related Apple frameworks to fix known radars with the least impact. The current set

PSPDFKit Labs 217 Aug 9, 2022
Simple UIButton subclass with additional state change animations (e.g. backgroundColor) and missing features

SimpleButton UIButton subclass with animated, state-aware attributes. Easy to subclass and configure! Full API docs Usage Just create your own SimpleB

Andreas Tinoco Lobo 169 Sep 14, 2022
Eazy is the missing piece in your SwiftUI and UIKit application.

Eazy is the missing piece in your SwiftUI and UIKit application. It aims at harmonizing how your views communicate with the model and vice versa in a clear and consistent way. Eazy can be used on any Apple platform.

Johan Thorell 7 Sep 18, 2022
Xcode Plugin helps you find missing methods in your class header, protocols, and super class, also makes fast inserting.

FastStub-Xcode Life is short, why waste it on meaningless typing? What is it? A code generating feature borrowed from Android Studio. FastStub automat

mrpeak 509 Jun 29, 2022