1

I have a shared instance of a class in Swift that I'm using in Objective-C. I'm unable to create the shared instance and use the instance function. Here's my Swift code.

class VideoPlayerSignaler: NSObject {
    static let sharedInstance = VideoPlayerSignaler()

    let playerAction = Signal<PlayerAction>()

    private override init() {

    }

    func firePlayerAction(action: PlayerAction) {
        playerAction.fire(action)
    }
}

Here's my Objective-C code.

VideoPlayerSignaler *signaler = [VideoPlayerSignaler sharedInstance];

// This is the line that is producing the issue. 
// It's as if the signaler variable is a Class Instance
[signaler firePlayerAction: PlayerAction.Stop];

The error I'm producing states that firePlayerAction does not exist. In essence, Objective C believes the signaler variable to be a class instance.

What am I doing wrong and how do I fix it so that signaler is a shared instance of VideoPlayerSignaler?

thank_you
  • 11,001
  • 19
  • 101
  • 185
  • 1
    If you post your code for the signal class as well as the firstPlayerAction in Objective-C, I may be able to help. – dhint4 Oct 21 '15 at 03:50
  • What issue does it produce? – Krypton Oct 21 '15 at 03:55
  • I can give you the library code. `https://github.com/artman/Signals` – thank_you Oct 21 '15 at 03:58
  • In fact, signaler here is really a "Class instance" – Krypton Oct 21 '15 at 04:05
  • That's what I thought. XCode doesn't recognize the function or the instance variable. – thank_you Oct 21 '15 at 04:09
  • What is `PlayerAction`? Is it an enum? Is it marked `@objc`? Then you probably need `PlayerActionStop`. – jtbandes Oct 21 '15 at 04:15
  • It's not but I'll fix that once I can figure out how to get an instance of `VideoPlayerSignaler`. – thank_you Oct 21 '15 at 04:17
  • I would love to know why someone thinks this question should be closed. Telling me why it's irrelevant helps me and others improve the question. – thank_you Oct 21 '15 at 06:38
  • My guess would be the `PlayerAction` enum. Is it an `@objc` enum? If not, it needs to be. And if it is, the cases export to ObjC like `PlayerActionStop`, not `PlayerAction.Stop`. – rickster Oct 21 '15 at 18:16
  • @rickster, Never thought that would be it. I knew I had to add the `@objc` but I didn't think it would be the issue. Post the answer and I'll give credit! – thank_you Oct 21 '15 at 18:30

1 Answers1

2

There's nothing wrong with your Swift, or with how you access the singleton instance from ObjC — the problem is the enum value you're passing to it.

Presumably your enum declaration looks something like this:

enum PlayerAction: Int {
    case Stop, Collaborate, Listen // etc
}

To make your enum accessible to ObjC, you need to preface the declaration with @objc:

@objc enum PlayerAction: Int { /*...*/ }

This makes it appear as a Cocoa-style NS_ENUM declaration in ObjC, creating global symbols for case names by concatenating the Swift enum type's name with the case names:

typedef NS_ENUM(NSInteger, PlayerAction) {
    PlayerActionStop = 1,
    PlayerActionCollaborate,
    PlayerActionListen, // etc
};

So those names are what you should be passing when you call a method taking an enum value from ObjC:

[signaler firePlayerAction: PlayerActionStop]; // NOT PlayerAction.Stop

(The only docs I can find to cite for this are buried in the Attributes chapter in The Swift Programming Language — scroll down the to objc attribute.)

rickster
  • 124,678
  • 26
  • 272
  • 326