1
votes

In framework we are using Swift and ObjC, so that Swift instances are instantiated within ObjC methods. To be able to do so, we had to make those swift files public/open, so they appear in SWIFT_INSTALL_OBJC_HEADER (OurModule-Swift.h), which is then imported by ObjC. The problem is that we'd like to hide those Swift classes from public interface of framework. Apple says:

For framework targets, only declarations with the public or open modifier appear in the generated header. 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 3.1).

so in theory it should be possible to have internal swift classes created from ObjC, but it doesn't seem to work. Any ideas?

1

1 Answers

1
votes

The documentation you quoted mentions only internal methods and properties, not classes. The same documentation also says, in a different section:

Swift methods and properties that are marked with the internal modifier and declared within a class that inherits from an Objective-C class are accessible to the Objective-C runtime. However, they are not accessible at compile time and do not appear in the generated header for a framework target.

See Importing Swift into Objective-C at https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID122

Thus you can make Swift classes public, so they are usable in the Objective-C part of your framework, but keep methods and properties of those classes internal. Since they are not available at compile time, you can let the Objective-C code know about them by using class extensions a.k.a anonymous categories.

Suppose you have the following Swift class whose implementation you want to hide:

public class SecretSwiftClass : NSObject {    
    func swiftFun(arg1 a : Int32, arg2 b : Int32) -> Int32 {
        return a + b
    }
}

In your framework's Objective-C code you might use the internal swiftFun() method as follows:

#import "YourProduct-Swift.h"

// Use an extension to let the compiler know about the hidden method
@interface SecretSwiftClass ()
-(int32_t)swiftFunWithArg1:(int32_t)l arg2:(int32_t)m;
@end

// You will make this one visible to client code via the
// framework's umbrella header
@implementation PublicOCClass : NSObject

-(int32_t) ocFun:(int32_t)int1 :(int32_t)int2 {
    SecretSwiftClass * sc = [[SecretSwiftClass alloc] init];
    return [sc swiftFunWithArg1:int1 arg2: int2];
}

@end