Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1153 from baskren/gh-1112
Browse files Browse the repository at this point in the history
Fix to fatal iOS 13 memory leak when using TextToSpeach.SpeekAsync #1112
  • Loading branch information
Redth committed Mar 25, 2020
2 parents e9d62fc + 852e563 commit a610b50
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions Xamarin.Essentials/TextToSpeech/TextToSpeech.ios.tvos.watchos.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -8,14 +9,18 @@ namespace Xamarin.Essentials
{
public static partial class TextToSpeech
{
static readonly Lazy<AVSpeechSynthesizer> speechSynthesizer = new Lazy<AVSpeechSynthesizer>();

internal static Task<IEnumerable<Locale>> PlatformGetLocalesAsync() =>
Task.FromResult(AVSpeechSynthesisVoice.GetSpeechVoices()
.Select(v => new Locale(v.Language, null, v.Language, v.Identifier)));

internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default)
internal static async Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default)
{
var speechUtterance = GetSpeechUtterance(text, options);
return SpeakUtterance(speechUtterance, cancelToken);
using (var speechUtterance = GetSpeechUtterance(text, options))
{
await SpeakUtterance(speechUtterance, cancelToken);
}
}

static AVSpeechUtterance GetSpeechUtterance(string text, SpeechOptions options)
Expand Down Expand Up @@ -44,24 +49,23 @@ static AVSpeechUtterance GetSpeechUtterance(string text, SpeechOptions options)
internal static async Task SpeakUtterance(AVSpeechUtterance speechUtterance, CancellationToken cancelToken)
{
var tcsUtterance = new TaskCompletionSource<bool>();
var speechSynthesizer = new AVSpeechSynthesizer();
try
{
speechSynthesizer.DidFinishSpeechUtterance += OnFinishedSpeechUtterance;
speechSynthesizer.SpeakUtterance(speechUtterance);
speechSynthesizer.Value.DidFinishSpeechUtterance += OnFinishedSpeechUtterance;
speechSynthesizer.Value.SpeakUtterance(speechUtterance);
using (cancelToken.Register(TryCancel))
{
await tcsUtterance.Task;
}
}
finally
{
speechSynthesizer.DidFinishSpeechUtterance -= OnFinishedSpeechUtterance;
speechSynthesizer.Value.DidFinishSpeechUtterance -= OnFinishedSpeechUtterance;
}

void TryCancel()
{
speechSynthesizer?.StopSpeaking(AVSpeechBoundary.Word);
speechSynthesizer.Value?.StopSpeaking(AVSpeechBoundary.Word);
tcsUtterance?.TrySetResult(true);
}

Expand Down

0 comments on commit a610b50

Please sign in to comment.