'static let sharedInstance not accessible from Objective-C code

Problem:

The declared static let sharedInstance is not accessible from Objective-C code when building the main app target.

Code:

    @objc public protocol ManagedObjectContextProvider {
          var context: NSManagedObjectContext { get }
    }

@objc public final class ManagedObjectContextProviderImpl: NSObject, ManagedObjectContextProvider {
    public static let sharedInstance: ManagedObjectContextProvider = ManagedObjectContextProviderImpl()
    
    override private init() {}
    
    public var context: NSManagedObjectContext {
        return NSManagedObjectContext.mr_default()
    }
}

Context:

  • This file is contained in 2 targets [main iOS App and Share extension]

  • In the swift to objc generated header of the main app the interface of the swift class is generated as follows:

      @class NSManagedObjectContext;
    
      SWIFT_PROTOCOL("_TtP4<#MyAppName#>28ManagedObjectContextProvider_")
      @protocol ManagedObjectContextProvider
      @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
      @end
    
    
      SWIFT_CLASS("_TtC4<#MyAppName>32ManagedObjectContextProviderImpl")
      @interface ManagedObjectContextProviderImpl : NSObject <ManagedObjectContextProvider>
      - (nonnull instancetype)init SWIFT_UNAVAILABLE;
      @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
      @end
    
  • In the swift to objc generated header of the share extension the interface of the swift class is generated correctly and is:

      @class NSManagedObjectContext;
    
      SWIFT_PROTOCOL("_TtP4<MyAppName>28ManagedObjectContextProvider_")
      @protocol ManagedObjectContextProvider
      @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
      @end
    
    
      SWIFT_CLASS("_TtC4<MyAppName>32ManagedObjectContextProviderImpl")
      @interface ManagedObjectContextProviderImpl : NSObject <ManagedObjectContextProvider>
      SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong)       id <ManagedObjectContextProvider> _Nonnull sharedInstance;)
      + (id <ManagedObjectContextProvider> _Nonnull)sharedInstance SWIFT_WARN_UNUSED_RESULT;
      - (nonnull instancetype)init SWIFT_UNAVAILABLE;
      @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
       @end
    
  • MyAppName specified above is the module name used when generating the Swift to Obj-C header and is the same for both main target and share extension

What I've tried:

  1. Copy the same class declaration in both headers [tricks the compiler but fails at runtime with "unrecognized selector"]
  2. Modify the module name of the extension so that it would have a diff module name than the target

What not to propose as a solution:

  1. To use a different module instead of files belonging to 2 targets


Solution 1:[1]

To make members (also static) accessible to ObjC code, you need to add @objc modifier to them, or @objcMembers modifier to class (which is a syntactic sugar to marking all the members with @objc). Read more in documentation.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Milan Nosá?