0

My framework contains a protocol that allows conforming types to describe themselves. One of its requirements is a static member containing the name of the type. This can be used as (for example) the header of a SwiftUI.List displaying a list of conforming types.

public protocol Describable: Identifiable {
    static var className: LocalizedStringResource { get }

    // ...
}

struct ItemList<I: Describable>: View {
    let items: [I]
    
    var body: some View {
        Text(I.className)
            .font(.title)
        List(items) { item in
            // ...
        }
    }
}

The above works fine, but I want to be able to annotate the key with a comment, and to be able to vary the key by plurality, so that a struct Building { ... } can have a localized key for the plural 'Buildings' (and equivalent plural forms in other languages).

Optimally, the protocol should provide this functionality automatically to conforming types, however I don't know how to achieve this properly with LocalizedStringResource and the new string catalog (Localizable.xcstrings). The keys being added to my project contain a second variable instead of the class name (e.g. %1$lld %2$@). Below are some of my attempts:

public protocol Describable: Identifiable {
    static var localizedClassName: LocalizedStringResource { get }
    static var className: String { get }
    static var staticClassName: StaticString { get }
    // ...
}

extension Describable {
    
    static func classDescription(for count: Int) -> LocalizedStringResource {
        "\(count) \(className)"
    }
    
    static func classDescription2(for count: Int) -> LocalizedStringResource {
        "\(count) \(staticClassName.asString)"
    }
    
    static func classDescription3(for count: Int) -> LocalizedStringResource {
        LocalizedStringResource("\(count) \(staticClassName.asString)", comment: "Type Description")
    }
}

private extension StaticString {
    var asString: String {
        self.withUTF8Buffer { String(decoding: $0, as: UTF8.self) }
    }
}

I've tried a few more variations, but the mixed usage of LocalizedStringResource, StaticString, String, String.LocalizationValue and other string literals makes my brain hurt and none of it looks correct anymore. What is the proper way to do this? Or am I trying to reinvent the wheel and does such functionality already exist within Swift?

4
  • You do indeed seem to be reinventing the wheel. String catalogs have pluralisation built-in. Just edit the string catalog. You don't need to change your Describable protocol at all. Commented Mar 14, 2024 at 21:17
  • For comments that's true I suppose, although if a project has many conforming types, I would've liked to be able to comment those automatically. However the 'vary by plural' option is disabled for the keys that are added. Commented Mar 14, 2024 at 21:21
  • For "vary by plural" to be enabled, you need a %lld or similar placeholder in the key. So you will need to add an extra key, in addition to just the word itself. Commented Mar 14, 2024 at 21:32
  • I realized my code didn't really show anything regarding plurality so I've edited it for clarity. Commented Mar 14, 2024 at 21:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.