Reputation: 123
I've been looking for documents of reasons of why a singleton method definition in Objective-C class is not available on the Swift interface on Xcode.
The Objective-C class is defined like this
/**
* A general accessor across the sample App to remove the dependency of QPSLibraryManager from resusable components.
*/
@interface QPSSharedAccessor : NSObject
/**
* Required by QPSLibraryManager and some UI components.
*/
@property (nonatomic, strong) QPSApplicationConfiguration *qpsConfiguration;
/**
* Provides Commands to app
*/
@property (nonatomic, strong) id<QPSAppController> appController;;
/**
* Shared singleton.
*/
+ (instancetype)sharedAccessor;
/**
* Returns access to a configuration manager
*/
- (QPSConfigurationManager *)configurationManager;
@end
On Swift Interface, its defined like this
/**
* A general accessor across the sample App to remove the dependency of QPSLibraryManager from resusable components.
*/
open class QPSSharedAccessor : NSObject {
/**
* Required by QPSLibraryManager and some UI components.
*/
open var qpsConfiguration: QPSApplicationConfiguration!
/**
* Provides Commands to app
*/
open var appController: QPSAppController!
/**
* Returns access to a configuration manager
*/
open func configurationManager() -> QPSConfigurationManager!
}
I'm expected to see the sharedAccessor() singleton method on Swift but it is missing as you can see. Calling the said method on a separate swift file results in a compiler error, saying that the sharedAccessor() method doesn't exist. Converting everything to Swift is not viable btw. Advice on fixing this problem?
Upvotes: 1
Views: 812
Reputation: 4891
After some experimentation, I see that sharedAccessor()
appears to have some special meaning. Using a different name for it, e.g. sharedAccessor1()
or sharedInstance()
, worked for me just fine. One related observation is that trying to call sharedAccessor()
when it is NOT part of the interface results in this error: Type QPSSharedAccessor has no member sharedAccessor
, which makes sense. However, adding sharedAccessor()
to the Objective-C code results in:
'sharedAccessor()' is unavailable: use object construction 'QPSSharedAccessor()'
Opening the error details sheds more light on this:
'sharedAccessor()' has been explicitly marked unavailable here (__ObjC.QPSSharedAccessor)
Now, renaming the QPSSharedAccessor
type to something else makes sharedAccessor()
acceptable, but if the new type name is, for example, QPSMyClass
, then naming the method myClass()
becomes a problem!
To work around this strange problem, evidently having to do with compiler internals, obscure method naming conventions, or a bug, you can simply rename the sharedAccessor()
method to something else. Alternatively, you can write a wrapper method in C or Objective-C and make it available to Swift via the bridging header. For example:
QPSSharedAccessor * getGlobalQPSSharedAccessor()
{
return [QPSSharedAccessor sharedAccessor];
}
You could also add a category to QPSSharedAccessor
with a method having a different name and delegating to sharedAccessor()
.
Also, please see if these references are useful:
Can't build in Xcode with error "[method] has been explicitly marked unavailable"
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html (see the Singleton section).
Upvotes: 1