Speak() not working on iOS


#1

My app works fine on Mac (Chrome & Safari), PC (Chrome & Mozilla) and Android (Chrome), but I can’t get a sound out of the few iPads and an iPhone 7 that I’ve tried it on.

The app works perfectly, but it won’t speak - the Speak() command seems to be broken on iOS.

Any ideas?

Thanks.


#2

Is this running as a web app or as a PhoneGap app?

I just tried the sample here. It worked fine as a web app.


#3

It’s running as a web app from my own server.

I’ve managed to simply recreate it. Create a new project (BASIC) with the following code:

Function Form1_onshow()
  Speak(“Hello”)
End Function

When I upload to my server and run on anything other than iPhone or iPad it says ‘Hello’ as expected. The iOS devices remain silent.

Now if I add a button to the form and an onclick event that does the same thing, that will work. It simply won’t work when run in the onshow() function.

It seems as if the iPad takes a while to load its text-to-speech engine, certainly longer than every other device (which doesn’t make sense considering how powerful it is).

Are you able to replicate the issue?


#4

We noted the issue during development. It does take time to load the libraries, so you can’t do Speak immediately on startup. You could use a SetTimeout to delay it a bit.

http://wiki.nsbasic.com/SetTimeout


#5

Oh, OK. Well that’s a bit of a nuisance.

I think, if possible, I’d prefer to only delay with a SetTimeout if it’s running on an iPhone or iPad. Could you please remind me which variable/property/command I should use to determine the OS of the device that the app is running in so I can do this?

Also, to save me some trial and error runs, would you happen to know how long the delay should be? :blush:

Thanks.


#6

Use this JavaScript statement to see if you’re running iOS.

const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

We haven’t done any work on figuring out what delay is needed.


#7

I’m afraid it’s not so straight forward. Looks like the problem is a little more complicated than expected.

I’ve created a new project (BASIC) in which I’ve added Button1 and Textarea1 to Form1 and the following code:

Function Form1_onshow()
   SetTimeout(delayedSpeak,10000)
End Function

Function delayedSpeak()
  Speak(“This is something being said.”)
  Textarea1.value="Delayed Speech"
End Function

Function Button1_onclick()
  Speak(“This is something being said.”)
  Textarea1.value="Button Pushed"
End Function

On any device other than an iOS device it will, as expected, say “This is something being said” and show ‘Delayed Speech’ in the text area after 10 seconds. However, the iOS devices will display ‘Delayed Speech’ in the text area after 10 seconds but will remain silent.

The iOS devices will, however, carry out the Speak instruction when you tap the button.

But the most interesting part is that if you run the app again and tap on the button before the 10 seconds are up, it will all work properly (i.e. it will speak correctly when the button is tapped but will also speak correctly once the 10 seconds are up as expected).

So it doesn’t seem as if it’s a delay in setting up the speech library - it seems more as if an event needs to be called, or a control needs to be tapped, or something similar in order to kick-start the speech engine/library.

Can this be fixed? :thinking:

Thanks.


#8

I have a hunch we’re running in to an iOS security feature.

The iOS camera cannot be activated by code alone: the user has to initiate the action by clicking a button. (Would you want your phone taking pictures without your permission?)

They may have done the same with speech. In a quick search, I was unable to confirm this: but you might have a look for the speechSynthesis.speak() function.