Reputation: 21
I'm working on a framework.
The library is written in Swift and I notice that when a class inherits from NSObject
or conforms to NSObjectProtocol
, its declaration can be found in *.framework/Headers/*-Swift.h
.
This class is available outside of the module in Objective-C code, so it became public.
Why does it happen if the access level is internal?
Upvotes: 1
Views: 389
Reputation: 32838
Internal Swift classes need to be available to the Objective-C code of that framework, however the only way Objective-C code can access the Swift classes is by importing the -Swift.h
header file.
Now, how can a Swift class be visible to Objective-C: it either needs to inherit NSObject
, or conform to NSObjectProtocol
. If any of these two conditions is fulfilled, and the class declaration is not decorated with @nonobjc
/private
/fileprivate
, then it will be exported to Objective-C via the -Swift.h
module header.
This is why any Swift classes that are exportable to Objective-C will automatically be present in the discussed header file. It's an (unfortunate) coincidence that for frameworks this results in the class being publicly available (due to the fact that any Objective-C declarations that appear in a header are public).
Now, if you want your class to not end up in the -Swift.h
header file, but still want to keep the NSObject(Protocol)
inheritance/conformance, a workaround would be to make your class generic, thus prohibiting its exposure to Objective-C. Note that this will also prevent the class from being available to Objective-C code in the same framework.
// the generic argument doesn't matter, it's only used to make the class
// Swift-only
class MyClass<T>: NSObject { }
The caveat would be that every time the class is used, you will need to specify a value for the generic argument. This can be avoided by adding an intermediary base class:
// just a class that inherits NSObject, but is not exported in the -Swift header
class Empty<T>: NSObject { }
class MyClass: Empty<String> { }
Upvotes: 0