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
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