2017-12-02 5 views
0

私はNSSpeechSynthesizerインスタンス上startSpeaking(String)メソッドを呼び出すと、デリゲートを設定して、話すには、次のデリゲートメソッドは決して火に過ぎず発生します。NSSpeechSynthesizerがその代理メソッドを呼び出さないのはなぜですか?

speechSynthesizer(_ sender: NSSpeechSynthesizer, 
       willSpeakWord characterRange: NSRange, 
         of string: String) 

func speechSynthesizer(_ sender: NSSpeechSynthesizer, 
      didFinishSpeaking finishedSpeaking: Bool) 

なぜ?私はスイフト4を使用しています。 XCode 9.1; MacOSの10.13.1

手順再現:

コンパイルして、次を実行します。

import AppKit 

class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate { 

    var str = "" 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) { 
     str = "spoke a word" 
    } 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) { 
     str = "finished speaking" 
    } 

} 

let mySpeaker = NSSpeechSynthesizer() 

let myDelegate = SynthDelegate() 

mySpeaker.delegate = myDelegate 

mySpeaker.startSpeaking("test string to read aloud") 

sleep(5) // keep alive while speaking 

print(myDelegate.str) 

期待される結果:

実際

を "話す終えました"結果:

""

更新

OOPers優れた答えは上に構築、新しいテストプロジェクトで、次WORKS:

import Cocoa 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 



    func applicationDidFinishLaunching(_ aNotification: Notification) { 
     // Insert code here to initialize your application 

     let mySpeaker = NSSpeechSynthesizer() 
     let myDelegate = SynthDelegate() 
     mySpeaker.delegate = myDelegate 
     mySpeaker.startSpeaking("test string to read aloud") 


     Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) {_ in 
      print(myDelegate.str) 

     } 
    } 

    func applicationWillTerminate(_ aNotification: Notification) { 
     // Insert code here to tear down your application 
    } 


} 


class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate { 
    var str = "" 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) { 
     str = "spoke a word" 
     print(str) 
    } 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) { 
     str = "finished speaking" 
     print(str) 
    } 
} 

答えて

1

あなたがプレイグラウンドで、あなたのコードをテストしていますか?とにかく、遊び場コードを含めてアプリ内でsleep()に決して電話するべきではありません。

これは、デリゲートメソッドの呼び出しなど、フレームワークを動作させるために必要な多くのアクティビティを防ぎます。遅れてコードを実行する必要がある場合は、Timerを使用できます。

遊び場でのテスト容易:

import AppKit 

class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate { 
    var str = "" 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) { 
     str = "spoke a word" 
     print(str) 
    } 

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) { 
     str = "finished speaking" 
     print(str) 
    } 
} 

let mySpeaker = NSSpeechSynthesizer() 
let myDelegate = SynthDelegate() 
mySpeaker.delegate = myDelegate 
mySpeaker.startSpeaking("test string to read aloud") 

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 

Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) {_ in 
    print(myDelegate.str) 
    PlaygroundPage.current.finishExecution() 
} 
+0

[OK]を、それは遊び場で作業されることを!これはNSSpeechSynthesizerのバグではないことを証明しています。 XCTestCaseテストのテストで同等のものは何でしょうか? – Mark

+1

@マーク、XCTestCaseはこの種の非同期機能をテストするための良いツールではありません。 XCTestCaseでのテストが必要な場合は、質問を更新して明示し、XCTestCaseの経験が豊富な人にアピールするようにしてください。 – OOPer

関連する問題