7

I can't access my Swift Singleton Class from my Objective-C ViewController.

Xcode does recognize my Swift Class, it builds, so I don't think it is a bridging header issue.

Here is my Swift Singleton Class :

@objc class MySingleton : NSObject {

    static let shared = MySingleton()

    private override init() {}
}

And then in my .m file I import this header :

#import "myProject-Swift.h"

And use the Singleton this way :

 MySingleton *testSingleton = [MySingleton shared];

or this way :

[MySingleton shared];

It does recognize the MySingleton class type, but I can't access any functions or properties of this class.

What am I missing? All the similar posts didn't help.

EDIT: I made a test function

func testPrint() {
   print("Singleton worked")
}

And called it this way in the objective-c file :

[[MySingleton shared] testPrint];

No known instance for selector 'testPrint'

  • MySingleton *testSingleton = [MySingleton shared]; by using this you are going to create another Instance while you had already Singleton. i guess you can directlly access any methods or properties by this : [[MySingleton shared] anyMethod]; – Er.Gopal Vasani Oct 26 '17 at 08:56
  • I have edited my question with an example –  Oct 26 '17 at 09:00
  • @GOPALVASANI you are not correct, it is a basic way of creation of singleton in swift. – Luzo Oct 26 '17 at 09:02
  • @Luzo . what is wrong with my suggestion ? i mean develper had already shared Instance then what the need of creating another one ? – Er.Gopal Vasani Oct 26 '17 at 09:03
  • @Balanced , can you please provide me your tried code. – Er.Gopal Vasani Oct 26 '17 at 09:04
  • 2
    Compare https://stackoverflow.com/q/44390378/2976878 – Hamish Oct 26 '17 at 09:15
  • Great stuff @Hamish. Good to know about this. Will definitely be helpful for the future. –  Oct 26 '17 at 09:18

3 Answers3

12

In your Swift Singleton class, add @objc for the method testPrint() like:

@objc func testPrint() {
   print("Singleton worked")
}

Now, you access the method from Objective-C class:

[[MySingleton shared] testPrint];
Imad Ali
  • 3,261
  • 1
  • 25
  • 33
  • 4
    Ok you are correct. But I also had to add @objc to the shared property. Seems weird. I thought doing it for the whole class would be enough. –  Oct 26 '17 at 09:12
0

use @objc attribute before the testPrint() function. refer documentation

To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class or it must be marked @objc.

Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
0

You need to add @objc to any property or function you want to expose to Objective-C, including the static shared property:

class MySingleton : NSObject {

    @objc static let shared = MySingleton()
    private override init() { }
    @objc func testPrint() { print("Singleton worked") }

}

Then, the call from Objective-C file:

MySingleton *singleton = [MySingleton shared];
[singleton testPrint];

Note that marking the whole class as @objc isn't a replacement for the above. It is actually not needed anymore, and it's enough to inherit from NSObject.

brkeyal
  • 1,317
  • 1
  • 16
  • 22