Reputation: 1302
My AVSpeechSynthesizer code is not working on device (iOS 10), but it worked on iOS 9.x and it is working now in simulator.
let str = self.audioOutput //just some string here, this string exists, and it's in english
let synth = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: str)
utterance.rate = AVSpeechUtteranceDefaultSpeechRate
let lang = "en-US"
utterance.voice = AVSpeechSynthesisVoice(language: lang)
synth.speakUtterance(utterance)
I'm getting this error:
MobileAssetError:1] Unable to copy asset attributes
Could not get attribute 'LocalURL': Error Domain=MobileAssetError Code=1 "Unable to copy asset attributes"
UserInfo={NSDescription=Unable to copy asset attributes}
0x1741495e0 Copy assets attributes reply: XPC_TYPE_DICTIONARY <dictionary: 0x1741495e0> { count = 1, transaction: 0, voucher = 0x0, contents =
"Result" => <int64: 0x1744203a0>: 1}
Before that there were error messages like that:
Unable to copy asset information from https://mesu.apple.com/assets/ for asset type
Does anyone know how to solve this issue? I know there is some workarounds (user has to go to Settings->General and switch Speak Selection, for example) but I don't think it's a real solution here.
Update: I created a new project (XCode8/Swift3/no other pods/frameworks and so on). It works in simulator, but it gives me the same errors on my device.
Update 2: It works on device. I have similar error messages (Unable to copy asset attributes and so on), but it works for now. I don't know what it was.
Upvotes: 24
Views: 10577
Reputation: 6888
Try this
import Foundation
import AVFoundation
let synthesizer = AVSpeechSynthesizer() //initialize synthesizer outside the function.
func speak(text: String) {
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
synth.speak(utterance)
}
Upvotes: 0
Reputation: 167
A similar problem for me got solved by changing the language to "es" (my device is in Spanish), then it worked. But I wanted the voice in English and it didn't speak with an English accent. It turns out that in my device I had in preferences/accessibility/voiceOver/rotor languages the voice Niky selected but not downloaded (probably deleted automatically after a long time not using it). I selected Alex, the default one, and it worked.
Upvotes: 0
Reputation: 7246
In my scenario, I could solve it by enabling Internet Connection in iPhone.
A speech recognizer recognizes only one language. When you use the default initializer, you get a speech recognizer for the device's current locale, if a recognizer is supported for that locale. Note that a supported speech recognizer is not the same as an available speech recognizer; for example, the recognizers for some locales may require an Internet connection. You can use the supportedLocales() method to get a list of supported locales and the isAvailable property to find out if the recognizer for a specific locale is available.
Upvotes: 2
Reputation: 470
I just ran into this same issue on an iPad Mini 4. This version doesnt have a physical switch. But if you open control center (swipe up), there is a Silent button. Turn this off and the issue fixes itself.
Upvotes: 11
Reputation: 5030
In my project, although I was having trouble getting synthesis to produce the first utterance after initialization, I was able to work around that by rearranging code. But I still have dozens of lines of garbage being spewed to the console when AVSpeechSynthesizer is initialized, and when its first utterance is produced. Here is a little sample:
2016-12-27 06:45:08.579510 SpeechBug1226[2155:859123] [MobileAssetError:1] Unable to copy asset attributes
2016-12-27 06:45:08.580248 SpeechBug1226[2155:859123] Could not get attribute 'LocalURL': Error Domain=MobileAssetError Code=1 "Unable to copy asset attributes" UserInfo={NSDescription=Unable to copy asset attributes}
2016-12-27 06:45:08.585959 SpeechBug1226[2155:859123] 0x174157fa0 Copy matching assets reply: XPC_TYPE_DICTIONARY <dictionary: 0x174157fa0> { count = 2, transaction: 0, voucher = 0x0, contents =
"Assets" => <data: 0x17426c700>: { length = 1237 bytes, contents = 0x62706c6973743030d4010203040506636458247665727369... }
"Result" => <int64: 0x174220180>: 0
I reproduced this in a small demo project and was unable to find a workaround. Sadly, I'm afraid that the correct answer to this question is to file a bug, which I just did :(
Upvotes: 3
Reputation: 301
Turn off your silent mode (the physical switch). It works in my case.
Upvotes: 30
Reputation: 2394
I have try your code with just one change and its working. Try this once
synth.speak(utterance)
My whole code is like
**`import AVFoundation`**
let str = "once" //just some string here, this string exists, and it's in english
let synth = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: str)
utterance.rate = AVSpeechUtteranceDefaultSpeechRate
let lang = "en-US"
utterance.voice = AVSpeechSynthesisVoice(language: lang)
synth.speak(utterance)
Upvotes: 1