Working on a mixed framework. imported inside the Obj-C file but the internal classes are not visible, only the public ones.
The documentation clearly states the internal clasees should be available between Swift and Obj-C:
Importing Swift into Objective-C
To import a set of Swift files in the same framework target as your Objective-C code, you don’t need to import anything into the umbrella header for the framework. Instead, import the Xcode-generated header file for your Swift code into any Objective-C .m file you want to use your Swift code from. Because the generated header for a framework target is part of the framework’s public interface, only declarations marked with the public modifier appear in the generated header for a framework target. You can still use Swift methods and properties that are marked with the internal modifier from within the Objective-C part of your framework, as long they are declared within a class that inherits from an Objective-C class. For more information on access-level modifiers, see Access Control in The Swift Programming Language (Swift 2).
Code Sample (Create a new project with a framework)
// SwiftObject.swift
public class SwiftObject: NSObject {
public class func doSomething() {}
}
internal class YetAnotherSwiftObject: NSObject {
internal class func doSomething() {}
}
// SomeObject.m file
@implementation SomeObject
- (void)someMethod {
[SwiftObject doSomething];
}
- (void)someOtherMethod {
[YetAnotherSwiftObject doSomething]; // Use of undeclared identifier
}
@end
Import Swift code into Objective-C within the same framework: Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes. Import the Swift code from that framework target into any Objective-C .
Unfortunately, it's not possible to subclass a Swift class in Objective-C. Straight from the docs: You cannot subclass a Swift class in Objective-C. See Apple's guide on interoperability for more details on what you can and cannot access with Objective-C.
The Swift Package Manager allows developers to build reusable components made up of Swift, Objective-C, Objective-C++, C, or C++ code that other developers can use in their own projects.
Unfortunately, that is the case. You cannot subclass a Swift class (even if it is a subclass of NSObject and available to the Objective-C runtime) because of deliberate limitations baked into Obj-C to block subclassing Swift classes in Obj-C code.
As indicated in the docs, declarations marked with internal
modifier don't appear in the generated header, so the compiler does not know about them and thus complaints. Of course, you could send messages using performSelector
approach, but that's not convenient and bug-prone. We just need to help the compiler know that those declarations are there.
First, we need to use @objc
attribute variant that allows you to specify name for your symbol in Objective-C:
// SwiftObject.swift
@objc(SWIFTYetAnotherSwiftObject)
internal class YetAnotherSwiftObject: NSObject {
internal class func doSomething() {}
}
And then you just need to create @interface
declaration with the methods you want to use in your code - so the compiler will be happy, and also apply SWIFT_CLASS
macro with the symbol name you've specified earlier - so the linker would pick the actual implementation:
// SomeObject.m file
SWIFT_CLASS("SWIFTYetAnotherSwiftObject")
@interface YetAnotherSwiftObject : NSObject
+ (void)doSomething;
@end
@implementation SomeObject
- (void)someOtherMethod {
[YetAnotherSwiftObject doSomething]; // Should work now !!!
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With