Finding the right Protocol for Generic that is interpolated into a String

I have a SubView that I wrote to avoid redundant code. It has a generic @Binding var that is presented to the user via string Interpolation (the view will be instantiated with a String or an Int). Because it is used in string interpolation, I get the error

No exact matches in call to instance method 'appendInterpolation'

if I don't have it conform to a protocol that lets swift know that the type can be used in string interpolation.

Doing a little research, I found StringInterpolationProtocol and ExpressibleByStringInterpolation as potential candidates, but Int doesn't conform to ExpressibleByStringInterpolation and String doesn't conform to StringInterpolationProtocol.

Given that both Strings and Ints can be used in string interpolation, is there another protocol that they both conform to that I can use?

Essentially what I want is to figure out what fits SomeProtocol here:

struct MySubView<T: SomeProtocol>: View {

    @Binding var theVariable: T

    var body: some View {
        HStack {
            Text("This part isn't important")
            Text("But this is \(theVariable)")
        }
    }

Or am I thinking of this the wrong way and there's a better way to go about this? Is an opaque type a better way to go?

Thanks!

Answered by OOPer in 692161022

Given that both Strings and Ints can be used in string interpolation

First of all, you need to distinguish string interpolation of which type. In case of Text, the type is LocalizedStringKey, not String. So, you may need to find how string interpolation of LocalizedStringKey is working.

LocalizedStringKey.StringInterpolation

As far as I read the parts Appending to an Interpolation and Instance Methods, I cannot find a common protocol which would work both for String and Int.


So, one possible work around, which does not need any protocols, would be converting theVariable to String before applying string interpolation of LocalizedStringKey.

struct MySubView<T>: View {

    @Binding var theVariable: T

    var body: some View {
        HStack {
            Text("This part isn't important")
            Text("But this is \(String(describing: theVariable))")
        }
    }
}

With this, you can use any arbitrary type for T, and with making the type conform to CustomStringConvertible, you can control the result of string interpolation for your custom type.

Accepted Answer

Given that both Strings and Ints can be used in string interpolation

First of all, you need to distinguish string interpolation of which type. In case of Text, the type is LocalizedStringKey, not String. So, you may need to find how string interpolation of LocalizedStringKey is working.

LocalizedStringKey.StringInterpolation

As far as I read the parts Appending to an Interpolation and Instance Methods, I cannot find a common protocol which would work both for String and Int.


So, one possible work around, which does not need any protocols, would be converting theVariable to String before applying string interpolation of LocalizedStringKey.

struct MySubView<T>: View {

    @Binding var theVariable: T

    var body: some View {
        HStack {
            Text("This part isn't important")
            Text("But this is \(String(describing: theVariable))")
        }
    }
}

With this, you can use any arbitrary type for T, and with making the type conform to CustomStringConvertible, you can control the result of string interpolation for your custom type.

Finding the right Protocol for Generic that is interpolated into a String
 
 
Q