1

How do I access to the shared instance of "SharedManager" declared in my Swift file from my Objective-C class?

Steps:

I have declared an object in a Swift file as following:

Swift Class Declaration:

From this [instructions][1] I did:

// Swift class
class SharedManager{
    static let sharedInstance = SharedManager()
}

From Objective-C class:

In AppDelegate.m:

#import "ProjectName-Swift.h"

@class SharedManager;
@interface AppDelegate ()
@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// How do I access to the shared instance of "SharedManager" ?

}    

  [1]: http://stackoverflow.com/questions/24024549/using-a-dispatch-once-singleton-model-in-swift
mm24
  • 9,280
  • 12
  • 75
  • 170

4 Answers4

1

To use a Swift class in Objective C, it must inherit from an Objective C class (such as NSObject), or be marked with @objc.

Either:

@objc class SharedManager {
    static let sharedInstance = SharedManager()
}

Or:

class SharedManager: NSObject {
    static let sharedInstance = SharedManager()
}

Then you can use it just like any other Objective C class:

SharedManager *manager = SharedManager.sharedInstance;
Alexander
  • 59,041
  • 12
  • 98
  • 151
1

Maybe late to the party, but you should also prepend the @objc marker also for the shared instance:

@objc
class VoiceShortcutsManager: NSObject {
    @objc static let shared = VoiceShortcutsManager()

    private override init() {
        super.init()
        updateVoiceShortcuts(nil)
    }

...

}

This way you can safely access the shared instance in objective-c:

...

[VoiceShortcutsManager shared];

...
valvoline
  • 7,737
  • 3
  • 47
  • 52
0

You need to do the following:

  1. #import "ProjectName-Swift.h" in the Objective-C implementation file (.m) where you want to refer to the Swift type.
  2. Subclass your SharedManager from NSObject:
class SharedManager: NSObject {
    static let sharedInstance = SharedManager()
}

This will work at least with Swift 2.3 and 3 (i.e. Xcode 8 & current macOS / iOS SDK versions, with or without "Use Legacy Swift Language Version" on in build configuration). I fail to remember if prior to Swift 2.3 you can make the above work with additionally marking the class with the @objc attribute or whether static variables declared in Swift are entirely unavailable to Objective-C code?

mz2
  • 4,672
  • 1
  • 27
  • 47
-1
 class MyClass { 
    private static let _sharedInstance = MyClass() 

    class func sharedInstance() -> MyClass { return _sharedInstance } 
} 

Retrieve the singleton via

MyClass.sharedInstance()
Bassam
  • 831
  • 8
  • 17
  • The bridging header file is for exposing Objective C to Swift, the opposite of what OP needs. OP needs to use the auto-generated header file created by Xcode, which they already have imported (`#import ProjectName-Swift.h`). – Alexander Oct 12 '16 at 08:31
  • I have the bridge header to export Swift classes as Alexander said – mm24 Oct 12 '16 at 08:37
  • class MyClass { private static let _sharedInstance = MyClass() class func sharedInstance() -> MyClass { return _sharedInstance } } Retrieve the singleton via MyClass.sharedInstance() – Bassam Oct 12 '16 at 08:43
  • Hi Bassam, adding the method worked. Would you be able to edit your answer reflecting this and then I'll accept it? – mm24 Oct 12 '16 at 09:14