简体   繁体   中英

Compile and runtime failures when importing interfaces with category extensions in XCode 7

I'm trying to get an example of running OpenEars with the RapidEars plugin running in Swift 2.2 (XCode 7.3.1). However, I suspect I'm having a larger issue with using Objective-C interfaces with extensions in a Swift project (or my understanding of how that works).

The OpenEars code is Obj-C. However I was able to get it running in my swift project through the standard Obj-C -> Swift translation techniques.

Abbreviated code follows. The full example is on a forked Github and updated to Swift-2.2: https://github.com/SuperTango/OpenEars-with-Swift-

This following example is working great. You can see the entire project by checkng out the "working-opears-swift2.2" tag.

OpenEarsTest-Bridging-Header.h:

#import <OpenEars/OELanguageModelGenerator.h>
#import <OpenEars/OEAcousticModel.h>
#import <OpenEars/OEPocketsphinxController.h>
#import <OpenEars/OEAcousticModel.h>
#import <OpenEars/OEEventsObserver.h>

ViewController.swift:

class ViewController: UIViewController, OEEventsObserverDelegate {

    var openEarsEventsObserver = OEEventsObserver()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadOpenEars()
    }

    func loadOpenEars() {
        self.openEarsEventsObserver = OEEventsObserver()
        self.openEarsEventsObserver.delegate = self

        var lmGenerator: OELanguageModelGenerator = OELanguageModelGenerator()

        addWords()
        var name = "LanguageModelFileStarSaver"
        lmGenerator.generateLanguageModelFromArray(words, withFilesNamed: name, forAcousticModelAtPath: OEAcousticModel.pathToModel("AcousticModelEnglish"))

        lmPath = lmGenerator.pathToSuccessfullyGeneratedLanguageModelWithRequestedName(name)
        dicPath = lmGenerator.pathToSuccessfullyGeneratedDictionaryWithRequestedName(name)
    }

    func startListening() {
        do {
            try OEPocketsphinxController.sharedInstance().setActive(true)
            OEPocketsphinxController.sharedInstance().startListeningWithLanguageModelAtPath(lmPath, dictionaryAtPath: dicPath, acousticModelAtPath: OEAcousticModel.pathToModel("AcousticModelEnglish"), languageModelIsJSGF: false)
        } catch {
            NSLog("Error!")
        }
    }

    // A whole bunch more OEEventsObserverDelegate methods that are all working fine...
    func pocketsphinxDidStartListening() {
        print("Pocketsphinx is now listening.")
        statusTextView.text = "Pocketsphinx is now listening."
    }

Up until this point, everything is working great.

However, In order to use the "RapidEars" plugin, the documentation ( http://www.politepix.com/rapidears/ ) says to:

  • Add the framework to the project and ensure it's being included properly.
  • import two new files (that are both "categories" to existing OpenEars classes):

     #import <RapidEarsDemo/OEEventsObserver+RapidEars.h> #import <RapidEarsDemo/OEPocketsphinxController+RapidEars.h> 
  • Change methods that used: startListeningWithLanguageModelAtPath to use startRealtimeListeningWithLanguageModelAtPath

  • add two new OEEventsObservableDelegate methods.

     func rapidEarsDidReceiveLiveSpeechHypothesis(hypothesis: String!, recognitionScore: String!) func rapidEarsDidReceiveFinishedSpeechHypothesis(hypothesis: String!, recognitionScore: String!) 

The new code can be found by checking out the rapidears-notworking-stackoverflow tag from the above github repo

Problem 1:

When doing completion in the XCode editor, the editor sees WILL perform autocompletion on the startRealtimeListeningWithLanguageModelAtPath method, however when the code is run, it always fails with the error:

[OEPocketsphinxController startRealtimeListeningWithLanguageModelAtPath:dictionaryAtPath:acousticModelAtPath:]: unrecognized selector sent to instance 0x7fa27a7310e0

Problem 2:

When doing auto completion in the XCode editor, it doesn't see the two new delegate methods defined in RapidEarsDemo/OEPocketsphinxController+RapidEars.h .

I have a feeling that these are related, and also related to the fact that they failing methods are defined as Categories to Objective-C classes. But that's only a guess at this point.

I've made sure that the RapidEars framework is imported and in the framework search path.

Can anyone tell me why this is happening? Or if there's some Swift magic incantation that I missed?

The problem could be the one described in the link below, where category methods in a static library produce selector not recognized runtime errors.

Technical Q&A QA1490: Building Objective-C static libraries with categories

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM