Fatal error calling TranslationSession.translate(String) in iOS 18

I'm trying to use the iOS 18 translation feature which works fine if I scroll slowly, but run into fatal errors when I scroll quickly.

In my view, I have this state property:

@State private var translationConfiguration: TranslationSession.Configuration?

In the body, I attach a .translationTask closure to the top-level view:

.translationTask(translationConfiguration) { translationSession in
  Task { @MainActor in
    ...
    let response = try await translationSession.translate(originalContent) // this line causes the fatal error.
  }
}

I also have an onAppear { } closure on the same top-level view, which sets translationConfiguration if it is nil, or calls translationConfiguration?.invalidate() if it's non-nil.

When I scroll quickly, the view presumably appears and disappears quickly, but it seems that the translationTask closure still runs after the view disappears.

I get this fatal error:

Translation/TranslationError+TranslationOnly.swift:54: Fatal error: Attempted to use TranslationSession after the view it was attached to has disappeared, which is not supported. Instead of storing a TranslationSession instance outside of the .translationTask closure, trigger a .translationTask to run again on a visible view and use that TranslationSession instance.

The recommendation from the error message seems incorrect, though. I am not using the TranslationSession instance outside of the translationTask closure. I'm using it only inside of it.

I tried to keep an extra visible boolean property that gets set to true when the onAppear closure is called, and set to false when the onDisappear closure is called, and then I guard on that within the translationTask, but that doesn't fix the issue.

What am I missing?

I get the same error in the same place:

    .onChange(of: vm.appleTraslationSourceText, { _, newValue in
        guard configuration == nil else {
            configuration?.invalidate()
            return
        }
        configuration = TranslationSession.Configuration(
            source: sourceLanguage,
            target: targetLanguage)
    })
    .translationTask(configuration) { session in
        Task { @MainActor in
            do {
                let response = try await session.translate(vm.appleTraslationSourceText) // <- fatal error here
                targetText = response.targetText
            } catch {
                // code to handle error
            }
        }
    }

This code, like yours, is very similar to Apple's demonstration code for translationTask(_:action:)

In my app you tap words to get a translation. If I tap too quickly on different words the crash will occur generating this error:

Translation/TranslationError+TranslationOnly.swift:54: Fatal error: Attempted to use TranslationSession after the view it was attached to has disappeared, which is not supported. Instead of storing a TranslationSession instance outside of the .translationTask closure, trigger a .translationTask to run again on a visible view and use that TranslationSession instance.

and

Refusing new translation request because text session has already been cancelled

So my problem seems to occur when requesting a new translation before the previous one has been returned.

Your scrollview could be requesting translations very often when scrolling?

You must put translationtask somewhere that won’t be removed from view hierarchy

Fatal error calling TranslationSession.translate(String) in iOS 18
 
 
Q