skip to Main Content

I have a binary Swift xcframework which references two other open-source Swift frameworks (built from source).

My framework along with its dependencies are built with the BUILD_LIBRARY_FOR_DISTRIBUTION option enabled (in order to support module stability).

This setup has worked fine for many years, but now when building my framework in Xcode 12.5 or above, I’m getting the following dyld error when an app using the framework is compiled in Xcode <12.5:

dyld: Symbol not found: __ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E

I do not seem to be the only one experiencing this problem. A look on Github provides a number of other frameworks experiencing the same issue in Xcode 12.5.

It is suggested here that this issue is being caused by the following warning apparently now causing this fatal error:

Using ‘class’ keyword for protocol inheritance is deprecated; use ‘AnyObject’ instead

I note that the affected dependency involved in my case (Starscream) has not yet changed the class keyword to AnyObject, however I have not (yet) verified this is definitely the cause.

Unfortunately there is very little documentation out there about this issue, but it seems like it could potentially be quite widespread and increasing in prevalence as people upgrade to Xcode 12.5+, and more binary frameworks are built against this new version.

Does anyone have any ideas about how this can be resolved/mitigated, other than downgrading to Xcode 12.4?

2

Answers


  1. We ran into this issue as well when updating to Xcode 12.5. According to Apple, "module stability" only ensures that frameworks built in older versions of Xcode will work in newer versions of Xcode. Up until 12.5, it has conveniently worked the other way around as well, but it seems like they decided to make some breaking changes.

    The workaround that we’ve been doing is using the xcodebuild system of 12.4 to compile our frameworks dependencies, while still using the 12.5 GUI for daily development. Switching to the older build is done by downloading the Xcode from the Developer Downloads and renaming it Xcode_12_4.

    export DEVELOPER_DIR=/Applications/Xcode_12_4.app/Contents/Developer

    Although, because of this definition of module stability, I would strongly advise building with the minimum version of Xcode that your framework officially supports. (which must be at least 12.0 to submit to the App Store) This would ensure that there would be no possible issues with anyone using your framework in an older Xcode version.

    I know that’s a pretty disappointing non-answer, but it can be a fairly sustainable process. Framework development on iOS seems to be moving in the direction of requiring the developers to use the minimum version of xcodebuild that they expect their implementers to be using.

    Another work-around that is sometimes available:

    This issue can be avoided by building your dependencies from source (assuming their license permits it). We built Starscream from source and it works quite well. (i.e. looking at the dependency GitHub if they post their source code, then copying it into a directory in your framework)

    Login or Signup to reply.
  2. We hit

    dyld: Symbol not found: __ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E
      Referenced from: our.framework/our
      Expected in: .../PromiseKit/PromiseKit.framework/PromiseKit
     in .../Foo.app/Frameworks/our.framework/our
    

    with our framework which we distribute as binary. We were still using an old version of PromiseKit (6.10) which contains

    public protocol Thenable: class {}
    

    Updating to a newer version which is changed to Thenable: AnyObject resolved the issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search