I've been trying to create a XCFramework and having some difficulties with the .swiftinterface file that presents error. I've created a sample project to simplify the problem:
This is my framework code:
import UIKit
@objc public class LoveThis: NSObject {
@objc public enum GreatEnum : NSInteger {
case First
case Second
}
@objc public static func helloWorld(){
print("Hello World!")
}
@objc public static func helloGreatEnum(myEnum: GreatEnum){
print("GreatEnum")
}
@objc public static func helloAwesomeEnum(myEnum: AwesomeEnum){
print("AwesomeEnum")
}
}
@objc public enum AwesomeEnum : NSInteger {
case First
case Second
}
After I've create my XCFramework, trying to import it gives me "Failed to load module"
and these errors:
It's not your fault; it's a longstanding bug/limitation in Swift that if you have a type and a framework with the same name, the name is always assumed to refer to the type. @beccadax is looking at some alternate ways to provide a module name in Pitch: Fully qualified name syntax that the module interface generator will be able to use; for now, though, you can work around this issue by renaming either your framework or the type in it. :-(
My framework is already in production so I'm not so inclined to change the name of the framework or type.
Another work around I've found is to process the .swiftinterface files using a script and remove all the occurrences of LoveThis. which yields valid .swiftinterface files.
It seems like everything is working as it should after that. No idea if there are any pitfalls I'm not aware of.
@jrose Would you consider this a valid workaround?
It's not a 100% valid workaround because now you're relying on the unqualified types always having the same behavior even if your dependencies change. I don't foresee any problems if you ship that way today, but one of the goals of module interfaces is to work with next year's Swift and next year's dependent libraries, and that only applies to module interfaces as generated from the compiler.
So, I've run into this same issue and am beginning to use the workaround of renaming the module. One big worry I have though is that the .swiftinterface is essentially invalid, but the compiler did not catch that until another package tried to consume it.
Is there some build setting I can enable to tell the compiler to validate the .swiftinterface it is generating? If not, I will file a bug to have that added. "Module stability" doesn't really exist if the .swiftinterface is invalid.
There isn’t currently a way to have the interface automatically validated. There is a compiler mode, -compile-module-from-interface, that you could probably use in a build step or something to manually validate the interface.
I've just hit hundreds of these errors. For a current project I switched to the Swift-for-tensorflow toolchain and these errors showed up in a third-party framework I'm using. Why would a framework suddenly get all these errors?
As a first attempt at fixing it, I did recompile the framework (it's open source) using the new toolchain, but no luck.
I am seeing this where I have an ObjC xcframework and I attempted to add a Swift struct and class to the framework. The Swift struct does not have the same name as my framework so it doesn't seem to me to be the same problem. Any thoughts given that information?