Are Swift Packages supported by String Catalogs?

Hello, do the String Catalogs (new in Xcode 15) support Swift Packages?

I've tried adding a new Localizable.xcstrings (string catalog) file to my package's resources folder.

Great! I then see this screen:

All good so far.

I then try to go and build my Swift Package... and nothing changes. The string catalog is never populated and I'm left with the same screen as above.

So, do string catalogs not support packages at this time or am I doing something wrong?

I was really hoping String Catalogs would work and save the day since Export Localizations also does not work for Swift packages that don't support macOS. 😔

Accepted Reply

I found my answer - yes they are supported. Two things to check:

  1. Make sure you're using Swift Tools 5.9 +
  2. I had to delete my existing Resources/ folder containing my *.lproj files.

Replies

I found my answer - yes they are supported. Two things to check:

  1. Make sure you're using Swift Tools 5.9 +
  2. I had to delete my existing Resources/ folder containing my *.lproj files.

Hi @kernelpop can you please mention your Swift Package Setup? A sample project would have been very helpful!!

This isn't working for me. I followed the example given in the video: https://developer.apple.com/videos/play/wwdc2023/10155/?time=1831

And it doesn't detect the default localization, so just shows an empty table. Tools version is 5.9

I even tried renaming the table, so it wouldn't conflict with the main application's Localizable table with no success.

// Catalogs file is then FakeModule.xcstrings
public func printModuleInfo() {
    
    let statement = String(localized: "TestString", table: "FakeModule")
    log.info("\(statement)")
}

Here is the package manifest:

// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription


let package = Package(
    name: "FakeModule",
    defaultLocalization: "en",
    platforms: [
        .iOS(.v16)
    ],
    products: [
        // Products define the executables and libraries a package produces, making them visible to other packages.
        .library(
            name: "FakeModule",
            targets: ["FakeModule"]),
    ],
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
        .target(
            name: "FakeModule",
            dependencies: [],
            path: "Sources"
        ),
        .testTarget(
            name: "FakeModuleTests",
            dependencies: ["FakeModule"]),
    ]
)
Add a Comment

You have to add defaultLocalization to your Package.swift and it should work

let package = Package(
    name: "YourName",
    defaultLocalization: "en", <---
    platforms: [
      .iOS(.v16)
    ],
...
  • that was already in my package manifest.

Add a Comment

The solution could be a mix of some of these things. I just now discovered that there are 2 ways to import a local package. You can do it via importing from the project inspector and provide a Local... package, or you can just drag the Package.swift file into your project, so that it doesn't look like an installed package dependency, but another target in the "workspace" (which is not a workspace), and then these values start to get populated at build time.