# Dynamically conforming a type to a protocol at runtime?

**URL:** <https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131>\
**Category:** Using Swift\
**Tags:** protocols, dynamic, existential, protocol-inheritance\
**Created:** [May 22, 2023, 5:13pm UTC](https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131 "2023-05-22T17:13:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![camelcode](https://avatars.discourse-cdn.com/v4/letter/c/e5b9ba/32.png) [@camelcode](https://forums.swift.org/u/camelcode)\
**Post date:** [May 22, 2023, 5:13pm UTC](https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131/1 "2023-05-22T17:13:00Z")

</div>

I'm pretty sure what I wrote in the title is impossible, but I'm hoping to find a solution to a problem and I think that the title sums it up well enough.

I have some protocol that defines a method:

```swift
protocol P {
    func p()
}

```

In my project, there will be various types that conform to `P`, and they will primarily be used as values of type `any P`. A type that conforms to `P` might be created, immediately type-erased to `any P`, then passed around as `any P` for the rest of its life. It's important that types that conform to `P` are (almost) only accessed as `any P`, since the types themselves are an implementation detail that should be hidden and easily swappable.

There are also a few additional protocols that inherit from `P`, that represent additional functionality that a type that conforms to `P` might want to implement. Types that conform to `P` can also conform to any number of these other protocols.

```swift
protocol PA: P {
    func a()
}
protocol PB: P {
    func b()
}

struct ImplP: P {
    func p() {}
}
struct ImplPA: PA {
    func p() {}
    func a() {}
}
struct ImplPAandPB: PA, PB {
    func p() {}
    func a() {}
    func b() {}
}

```

To access the functionality of these additional protocols, a value of type `any P` is conditionally downcast to the desired existential type.

```swift
func tryToCallA(p: any P) {
    if let pa = p as? any PA {
        pa.a()
    }
}

```

This system works great for types where I know what functionality they have at compile time and it feels very elegant. Unfortunately, there is a case where I need to decide which functionality a value of `P` has a runtime, when creating the value. (Its functionality is determined by data returned from a server).

First, before creating the value, data will be retrieved from a server that determines which functionality it supports. Then, a type that implements the proper protocols should be created and cast to `any P`.

One solution that I considered and rejected was creating separate types that conform to `P` for each possible set of functionality.

```swift
struct ServerP: P { ... }
struct ServerPA: PA { ... }
struct ServerPB: PB { ... }
struct ServerPAandPB: PA, PB { ... }

```

Depending on the data returned from the server, one of these types would be created, and cast to `any P`.

This solution isn't really practical, since the number of `ServerX` types needed grows exponentially as more protocols that inherent from `P` are added. In the actual project, there would be more than 2.

This is where the title comes in. Ideally, I could create only 1 `ServerP` type, that at initialization I specify which functionality it should implement based on the network data. The type somehow stores that info as fields, maybe optional function types.

```swift
struct ServerP: ?? {
    func p() // should always implement `P`
    let a: Optional<() -> Void> // might or might not implement `PA`, only known at runtime.
    let b: Optional<() -> Void>
}

```

Hopefully that makes sense.  
When it is cast to a type like `any PA`, it checks whether it has an `a()` method or something, then succeeds or fails based on that. Unfortunately, I'm 99% sure this isn't possible with swift's type system - I can't think of any way of achieving it. Maybe there's some dirty trick with objective-c? But I'd rather stick to pure swift if possible.

Fundamentally I feel like this should be possible, but idk if theres any nice way to do it with protocols.

Any ideas?

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [May 22, 2023, 6:25pm UTC](https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131/2 "2023-05-22T18:25:10Z")

</div>

Would it be feasible to do something _like_ this by manually implementing e.g. `AnyPA` and `AnyPB` type erasers that look like:

```swift
struct AnyPA: PA {
  var _a: () -> Void
  init(a: @escaping () -> Void) {
    self._a = a
  }
  
  func a() {
    _a()
  }
}

protocol P {
  func f()
  var a: any PA { get }
  var b: any PB { get }
}

struct ServerP: P {
  func p() { ... }
  let a: any PA?
  let b: any PB?

  init(a: @escaping () -> Void, b: @escaping () -> Void) {
    a = AnyPA(a: a)
    b = AnyPB(b: b)
  }
}

```

and then rather than casting `as? PA` you'd do `if let a = p.a` to extract the implementation dynamically.

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [May 22, 2023, 6:57pm UTC](https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131/3 "2023-05-22T18:57:55Z")

</div>

In the example you wrote, there are 3 protocols. `P`; `PA`, which inherits from `P`; and `PB`, which also inherits from P. You're trying to dynamically construct a type that **will** conform to P and **may** conform to A **and/or** B. I think you could do it this way.

```swift
struct AWrapper<T: P>: PA { 
  var wrappedValue: T
  var _a: () -> Void
  func p() { wrappedValue.p() }
  func a() { _a() }
}

extension AWrapper: PB where T: PB {
  func b() { wrappedValue.b() }
}

struct BWrapper<T: P>: PB { 
  var wrappedValue: T
  var _b: () -> Void

  func p() { wrappedValue.p() }
  func b() { _b() }
}

extension BWrapper: PA where T: PA {
  func a() { wrappedValue.a() }
}

```

Making these types still requires overloads for each protocol type, but the number of types is far smaller. In the solution you rejected, it would require N factorial types, where N is the number of protocols you use. With this solution, you just need N types and N extensions for each type, which is a lot more manageable. Once you have these types, you could dynamically create a type conforming to either A or B or A & B.

```swift
func loadDataFromServer() -> any P {
  let conformsToA = Bool.random()
  let conformsToB = Bool.random()
  let data: any P = URLSession.shared.grabAwesomeDataConformingToP()

  if conformsToA && conformsToB {
    return AWrapper(wrappedValue: BWrapper(wrappedValue: data) { /* code here */ } ) { /* code here */ }
  } else if conformsToA {
    return AWrapper(wrappedValue: data) { /* code here */ }
  } else if conformsToB {
    return BWrapper(wrappedValue: data) { /* code here */ }
  } else {
    return data
  }
}

```

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [May 22, 2023, 7:09pm UTC](https://forums.swift.org/t/dynamically-conforming-a-type-to-a-protocol-at-runtime/65131/4 "2023-05-22T19:09:24Z")

</div>

You could add some functions to make the process easier and type-erase the results while still keeping the generic conformances.

```swift
func addAConformance(to data: any P, conformance: @escaping () -> ()) -> any P {
    _addAConformance(to: data, conformance: conformance)
}

private func _addAConformance(to data: some P, conformance: @escaping () -> ()) -> some P {
    AWrapper(wrappedValue: data, _a: conformance)
}

func addBConformance(to data: any P, conformance: @escaping () -> ()) -> any P {
    _addBConformance(to: data, conformance: conformance)
}

private func _addBConformance(to data: some P, conformance: @escaping () -> ()) -> some P {
    BWrapper(wrappedValue: data, _a: conformance)
}

```

And then you could rewrite the original function like this.

```swift
func loadDataFromServer() -> any P {
  let conformsToA = Bool.random()
  let conformsToB = Bool.random()
  var data: any P = URLSession.shared.grabAwesomeDataConformingToP()

  if conformsToA {
    data = addAConformance(to: data) { /* code here */ }
  }

  if conformsToB {
    data = addBConformance(to: data) { /* code here */ }
  }
}

```
