Tijee
Tijee

Reputation: 503

Access Cocoapods resource_bundles

I'm struggling with localized resources defined in my own pod.

This pod uses Base Internationalization with the following files:

Base.lproj
|- Localizable.strings
|- MyViewController.xib

fr.lproj
|- Localizable.strings
|- MyViewController.strings

This is how they are defined in my podspec:

spec.resources = "MySDK/*.lproj/*"

In my app's Podfile, my pod is defined as a local dependency:

pod 'MySDK', :path => '../MySDK'

After I run pod install, I can see the exact same lproj folders in Development Pods/MySDK/Resources/MySDK.

MyViewController.xib is perfectly loaded and localized, I can change the language on my phone and the text changes accordingly.

In order to use the localized strings, I have defined a function in my SDK pod:

public func NSLocalizedIntentString(key: String) -> String {
    let sdkBundle = NSBundle(forClass: MySDKClass.self)
    return NSLocalizedString(key, tableName: nil, bundle: sdkBundle, value: key, comment: "")
}

It works, except that it only uses the string defined in Base.lproj, whatever the selected language on the phone or simulator.

I changed my podspec for:

spec.resource_bundles = {
    "MySDK" => ["MySDK/*.lproj"]
}

in order to load the bundle from the code, but now nothing works, the XIB can't get loaded. It's strange because in Development Pods I can still see the exact same structure as before, but with blue folder icons instead of yellow.

Here is how I load my XIB from my SDK, not from my app:

MyViewController.swift

public init(...) {
    ...
    super.init(nibName: "MyViewController", bundle: NSBundle(forClass: MyViewController.self))
}

I changed it for:

public init(...) {
    ...
    super.init(nibName: "MyViewController", bundle: NSBundle(path: NSBundle.mainBundle().pathForResource("MySDK", ofType: "bundle")!))
}

but it can't find the bundle.

I've read tons of documentation and forums since this morning without success, so any help would be more than welcome! :)

Upvotes: 8

Views: 4222

Answers (2)

Russell Austin
Russell Austin

Reputation: 409

I've been struggling with this on and off for a week.

The most elucidating thing I found so far was this: https://github.com/CocoaPods/CocoaPods/pull/4635

The above pull requests states in order to use resource_bundle you have to use the RESOURCEDIR/**/* glob pattern. It doesn't seem to matter what RESOURCEDIR is. I had been trying all sorts of things, but that **/* glob results in Xcode recognizing the localization directories.

You can try to reproduce my results

  1. Use pod lib create to create a new project
  2. Select Yes to include a demo application when prompted
  3. Use Finder to go to the Assets folder and add a Base.lproj directory
  4. In the podspec file, uncomment the s.resource_bundles section and change *.png to **/*
  5. Use the terminal to run pod install

Now in Xcode you should see the Assets folder with a Base.lproj folder.

  1. Add an xib or storyboard to the Base.lproj.
  2. Add a label that you want to translate.
  3. Add a class to support the xib or storyboard
  4. Run pod install again to bring in the new file
  5. Select the Pods project in the project navigator
  6. Run Editor > Export for Localization.

That should produce an XLIFF file you can use to make translations, then use the Editor > Import Localizations to bring in the translations.

Note You might have to run Build > Clean after importing your translations.

Note It seems the project that is including the pod also has to support localization.

Upvotes: 1

Tijee
Tijee

Reputation: 503

I finally figured it out.

  1. I switched back to spec.resources instead of spec.resource_bundles in my podspec because I couldn't access the generated bundle.
  2. Then I had to turn off localization for the XIB, because I realized that the resources in the lang subdirectories are not compiled. Thus, the XIB are now outside the lproj directories.

    My new podspec:

    spec.resources = "MySDK/*.lproj", "MySDK/*.xib"
    

    Note that I copy the lproj directories themselves (*.lproj), not the content of the lproj directories (*.lproj/*), because the Localizable.strings would override each other. I need to keep them in their lang subdirectories.

  3. Finally, I access the SDK bundle with:

    NSBundle(forClass: MySDKClass.self)
    

I'm still not 100% satisfied because I didn't manage to use the new spec.resource_bundles property. But anyway, it works.

Upvotes: 4

Related Questions