1

I am facing the above error while trying this:

    protocol Style {}
    
    struct StyleA: Style {}
    struct StyleA: Style {}
    struct StyleA: Style {}

    struct Preset: Identifiable {
        let id: UUID = UUID()
        let title: String
        let style: Style
    }

    extension View {
        public func applyStyle<S>(_ style: S) where S : Style {
            // USe the style here
        }
    }
    

    // Initializg the data
    static let mockedData: [Preset] = [
        .init(title: "Title A", style: StyleA()),
        .init(title: "Title A", style: StyleB()),
        .init(title: "Title A", style: StyleC()),
    ]
    
// This line gives the error
    myView.applyStyle(mockedData.first!.style)


How can I fix it? Shouldn't it resolve the concrete type?

Thanks for your help.

schinj
  • 794
  • 4
  • 19
  • Thats because in swift protocol does not confirm to itself. read: https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself – Sandeep Bhandari Feb 15 '21 at 16:19
  • one issue is that u have to make "protocol Style" public( since ur function is public – YodagamaHeshan Feb 15 '21 at 16:30
  • I guess , If u use applyStyle inside a body of a view ...then this function doesnt return a view , so that is also a function ...please add reproducable code . – YodagamaHeshan Feb 15 '21 at 16:32

3 Answers3

1

You're running into the problem of protocols not conforming to themselves. Your problem can be easily solved by making applyStyle non-generic, since Style can be used as a concrete type.

extension View {
    public func applyStyle(_ style: Style) {
        // USe the style here
    }
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • I would just remove `Style` from the method name `func apply(_ style: Style)` – Leo Dabus Feb 15 '21 at 16:54
  • @LeoDabus in that case, I think `func apply(style: Style)` would read more naturally, but this isn't really related to OP's question. – Dávid Pásztor Feb 15 '21 at 17:00
  • Sure not related to the question. Anyway I think that when there is a single parameter `style` is not needed and generally not used – Leo Dabus Feb 15 '21 at 17:16
0

Since the Preset member style is Style, not any concrete type, you don't need the applyStyle to be generic, you can simply say:

  public func applyStyle(_ style: Style) 
E. Vladov
  • 61
  • 1
  • 3
0

try

public protocol Style {}

struct StyleA: Style {}
struct StyleB: Style {}
struct StyleC: Style {}

struct Preset: Identifiable {
    let id: UUID = UUID()
    let title: String
    let style: Style
}

extension View {
    public func applyStyle(_ style: Style){
        // USe the style here
    }
}


// Initializg the data
let mockedData: [Preset] = [
    .init(title: "Title A", style: StyleA()),
    .init(title: "Title A", style: StyleB()),
    .init(title: "Title A", style: StyleC()),
]

myView.applyStyle(mockedData.first!.style)
Kstin
  • 659
  • 1
  • 4
  • 18