vinhnx / notes

my today I learn (TIL) journal, includes everything that I found interesting, not necessarily relates to programming
43 stars 2 forks source link

Apps that use libaries with localization files will result in (sometimes) unwanted languages #2

Open vinhnx opened 9 years ago

vinhnx commented 9 years ago

The problem

Recently I found out that, when we use Cocoapods to install third-party libraries, apps that use libaries with localization files will result in (sometimes) unwanted languages in the App Store page.

languages

As we know, when we archive, the final binary file that we use to submit to App Store will combine all containing targets in the workspace. It will also scan *.lproj and *.strings files, which will result to appear in the App Store page.

As far as I know, almost any popular library will have multiple localization files included in its bundle. To name a few: Facebook iOS SDK, Google, HockeyApp...

When we create a new project from Xcode, the app primary language will only be English. But in the in store page, all available languages will be shown, as seen on the above screenshot.

This could be easily overlook, except when the app have localization requirement.

How to solve

To solve this, there is an helper script that we can insert into the Podfile. The script will remove unwanted localizations it can find from Pods.xcodeproj.

With this approach, it can easily find and remove all localization files from pods bundle, if any. So we won't have to worry about the subsequent pod installs.

Reference: https://stackoverflow.com/a/31731683/1477298.

platform :ios, '9.0'

target 'MyApp-iOS' do

    use_frameworks!

    # Pods for MyApp-iOS

    # Remove unused languages from Pods
    pre_install do |installer|
        supported_locales = ['base', 'en', 'english']
        delete_unsupported_locales(installer.sandbox.root, supported_locales)
    end
end

def delete_unsupported_locales(root, supported_locales)
    Dir.glob(File.join(root, '**', '*.lproj')).each do |bundle|
        if (!supported_locales.include?(File.basename(bundle, ".lproj").downcase))
            puts "Removing #{bundle}"
            FileUtils.rm_rf(bundle)
        end
    end
end

After

screen shot 2015-08-28 at 9 39 53 sa

What to note here is the supported_locales variable.

For example, if we want to keep Chinese and English localizations, just add zh-Hans and en to supported_locales array.

For the complete list of ISO 639-1 language code, you can visit List of ISO 639-1 codes Wikipedia page.

anoop4real commented 8 years ago

I am not a pod expert, just want to ask a few things.

  1. I need to add the script in podfile right?
  2. Do I need to run a pod install or pod update after this? I asked this because I dont want my existing pod to be updated or modified.

thanks.

vinhnx commented 8 years ago

Hi there,

Thanks for asking question?

I'm also not a pod expert either, but I will try to answer you as detailed as possible. :)

1/ Yes, you need to add the script to your Podfile, typically at the end, right after the end statement of the first target block. So your Podfile will look like this.

source 'https://github.com/CocoaPods/Specs'

platform :ios, '7.0'
inhibit_all_warnings!

target 'MyApp' do
  pod 'AFNetworking'
end

# IMPORTANT! Remove unused localizations from pods
# this will prevent unwanted languages from appearing
# in the App Store page
# reference: http://stackoverflow.com/a/31828426
pre_install do |installer_or_rep|
    # backwards compatibility info http://blog.cocoapods.org/CocoaPods-0.38/
    supported_locales = ['base', 'en']

    if installer_or_rep.respond_to?(:installer)
        # pre 0.38.0
        installer_or_rep.pods.each do |pod|
            delete_unsupported_locales(pod.root, supported_locales)
        end
        else
        # post 0.38.0
        delete_unsupported_locales(installer_or_rep.sandbox.root, supported_locales)
    end
end

def delete_unsupported_locales(root, supported_locales)
    Dir.glob(File.join(root, '**', '*.lproj')).each do |bundle|
        if (!supported_locales.include?(File.basename(bundle, ".lproj").downcase))
            puts "Removing #{bundle}"
            FileUtils.rm_rf(bundle)
        end
    end
end

2/ You may need to run an pod install or pod update after this if you want the script to take effect. Otherwise it won't.

Don't worry, it will just look for all the the language files in the Pods you install, and will keep only the languages defined in supported_locales array, and then remove other ones.

Hope these will help you!

anoop4real commented 8 years ago

Thanks for the quick response...but right now I am facing some issue while doing pod update or install, which is not clear to me, can you see my post here http://stackoverflow.com/questions/26351086/how-to-update-a-single-pod-without-touching-other-dependencies/33099320#33099320

I am trying with below one also but facing issues while running update or install... https://github.com/dtorres/cocoapods-prune-localizations

vinhnx commented 8 years ago

Hi @anoop4real

Thanks for the quick response...but right now I am facing some issue while doing pod update or install, which is not clear to me, can you see my post here http://stackoverflow.com/questions/26351086/how-to-update-a-single-pod-without-touching-other-dependencies/33099320#33099320

I'm not really sure about this, I remember ran into this issue a while ago. Tried to update a specific pod but another pods got updated as well.

You can try asking this in the official Cocoapods repo or create new question StackOverflow.

I am trying with below one also but facing issues while running update or install... https://github.com/dtorres/cocoapods-prune-localizations

Sorry, I haven't used this tool before, so I can not help you.

vinhnx commented 6 years ago

Update 4/10/2017: updated script working with Cocoapod 1.3.1

tl;dr

platform :ios, '9.0'

target 'MyApp-iOS' do

    use_frameworks!

    # Pods for MyApp-iOS

    # Remove unused languages from Pods
    pre_install do |installer|
        supported_locales = ['base', 'en', 'english']
        delete_unsupported_locales(installer.sandbox.root, supported_locales)
    end
end

def delete_unsupported_locales(root, supported_locales)
    Dir.glob(File.join(root, '**', '*.lproj')).each do |bundle|
        if (!supported_locales.include?(File.basename(bundle, ".lproj").downcase))
            puts "Removing #{bundle}"
            FileUtils.rm_rf(bundle)
        end
    end
end