CocoaPods / Xcodeproj

Create and modify Xcode projects from Ruby.
http://rubygems.org/gems/xcodeproj
MIT License
2.35k stars 454 forks source link

Provide support for localised resources #85

Open epologee opened 11 years ago

epologee commented 11 years ago

An example project, created with regular Xcode, contains two localized Localizable.strings files:

xcode

When inspecting the project with xcodeproj show ..., it will list localized files like this:

  - Resources:
    - Localizable.strings:
      - en
      - nl

The underlying Localizable.strings-files are actually in two folders called en.lproj and nl.lproj:

finder

When trying to mimic this setup, with the same underlying paths I add them like this:

project.new_file('Resources/en.lproj/Localizable.strings', 'Resources/Localizable.strings/en')

But the result is different from the way Xcode treats these special cases:

xcodeproj

Would you know how to add these files, so Xcode treats them the same way, as when you add them the old-fashioned way?

Michenux commented 10 years ago

Any solution for this bug ?

lolgear commented 10 years ago

@Michenux I convert real path to xcodeproject path and add localizable strings. If you want I could share code with you

Michenux commented 10 years ago

@lolgear thanks a lot, i would prefer the fix to be included in the next release of xcodeproj. Maybe you can create a pull request.

martnst commented 10 years ago

As far as I know, for now pods need to provide localized files a bundle from which Localizable.strings can be access e.g. via NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment).

see this pods for example:

o15a3d4l11s2 commented 9 years ago

@lolgear would you please share the code for adding localizable resource? I have to add localizable images. Will your code help for this?

lolgear commented 9 years ago

@o15a3d4l11s2, ok, you can try it

haxpor commented 9 years ago

@epologee @Michenux I have successfully add Localizable.strings for additional languages added into the project. I created the script to manage my own project, and you can see it in following this line.

You can see the result from my tweet here (with photos).

Basically, if you take a look inside project.pbxproj file, those Localizable.strings are added into PBXVariantGroup. From my observation, there's only one of its instance. Thus the steps are as follows.

  1. Find PBXVariantGroup from #objects not from #groups. I wasted a couple of hours trying to get it from #groups without success.
  2. Now we're done adding localizable string to the project.
  3. Add Localizable.strings as part of #resources-build-phase for all project's targets (as needed). This means you need to iterate through all project's #native_targets, and add it properly and accordingly to its type (header => header-build-phase, source => sources-build-phase, and resources => resources-build-phase). You can look at Build Phases in Xcode to be familiar with those. Again, normally adding its folder i.e. fr.lproj which contains Localizable.strings inside instead of adding .strings file will do it very well. Check my addfile command here.
  4. You're done.
epologee commented 9 years ago

Sounds like @haxpor's solution could be part of Xcodeproj?

haxpor commented 9 years ago

Ohh sorry, I just found out that my code is not complete yet. I successfully did that because I added PBXVariantGroup via Xcode's way to add localization stuff first before executing my code, then the instance is found in project.pbxproj. That file didn't have PBXVariantGroup initially.

As observed in Ruby doc, I don't see how can I create PBXVariantGroup (if I miss anything please tell me). I think it might be a simple way but I just didn't see it yet. Just add a new group with isa is PBXVariantGroup in project.pbxproj file.

The following is what PBXVariantGroup looks like. screen shot 2015-08-04 at 10 22 22 pm

toshanmugaraj commented 8 years ago

I added new method for creating variant

class Xcodeproj::Project::Object::PBXGroup
  def new_vargroup(name, path = nil, source_tree = :group)
          group = project.new(Xcodeproj::Project::Object::PBXVariantGroup)
          children << group
          group.name = name
          group.set_source_tree(source_tree)
          group.set_path(path)
          group
  end
end

And loop through the files inside *.lproj folders to add the localisation

def addvariance (direc, current_group)
    Dir.glob(direc) do |item|
        new_item = File.basename(item)
        if !current_group[new_item]
           var_group = current_group.new_vargroup(new_item, nil, '<group>')  
           var_group.new_reference(item, '<group>') 
        else 
          current_group[new_item].new_reference(item, '<group>')
        end
    end
end
beribas commented 7 years ago

Was there an update on the issue? Would be great if this feature could find its way to Xcodeproj. Thanks @toshanmugaraj for advice, I used your code snippet, but had to add the files to target resources, too. Otherwise they are not copied.

simonseyer commented 7 years ago

I guess the ticket is solved since there is a new_variant_group method available in the PBXGroup class!?

o15a3d4l11s2 commented 7 years ago

@Eldorado234 , I am not sure how to generate localised resources records using new_variant_group that you mentioned. Could you please give more information?

simonseyer commented 7 years ago

Sure @o15a3d4l11s2. This is the respective PR in the project I'm working on: jensmeder/Phoenx/pull/31. It boils down to the following:

Given the file structure:

Resources
    en.lproj
        Localizable.strings
    de.lproj
        Localizable.strings

You have to create the variant group named Localizable.strings in the Resources group:

parent_group = project.main_group.find_file_by_path('Resources')
variant_group = parent_group.new_variant_group('Localizable.strings') 

Then you can add the actual translation files:

variant_group.new_file('en.lproj/Localizable.strings')
variant_group.new_file('de.lproj/Localizable.strings')