How to assign updated value to Text UI in extension function SwiftUI

176 views Asked by At

How to assign updated value to Text value in Extension SwiftUIenter image description here

extension Text {
    
    public func translate(text: String) -> Text{
        var translated = ""
        let conditions = ModelDownloadConditions(allowsCellularAccess: true, allowsBackgroundDownloading: true)
        GoogleTranslatorManager.shared.translator?.downloadModelIfNeeded(with: conditions) { error in
            guard error == nil else { return }
            GoogleTranslatorManager.shared.translator?.translate(text) { translatedText, error in
                guard error == nil, let translatedText = translatedText else {
                    //                    uiView.text = text
                    return
                }
                print(translatedText)
                translated = translatedText

               //**Here: How to assign updated Value to Text ** \\ 
           
            }
        }
        
        return Text(verbatim: translated)
    }
}
1

There are 1 answers

0
Paulw11 On

There are a few issues that I see with your approach.

First, it doesn't make much sense to put this extension on Text - Text is a view that displays a String. It makes more sense to put the extension on String.

Second, if you make an extension on String it would be more typical for the function to operate on self - that is the String instance itself, rather than accept an argument.

And the final issue is that the translation operations are asynchronous so you can't return a value.

As an extension on String it could look something like:

extension String {
   func translated(completionHandler: @escaping (Result<String, Error>) -> Void) ) {
       let conditions = ModelDownloadConditions(allowsCellularAccess: true, allowsBackgroundDownloading: true)
           
       GoogleTranslatorManager.shared.translator?.downloadModelIfNeeded(with: conditions) { error in
            guard error == nil else { 
               completionHandler(.failure(error))
            }
            GoogleTranslatorManager.shared.translator?.translate(self) { translatedText, error in
                guard error == nil, let translatedText else {
                   completionHandler(.failure(error))
                }
                completionHandler(.success(translatedText))
            }
        }
    }
}

And you would call it something like:

let someString = "parlez vous français"
someString.translated { result in 
    switch result {
        case .failure(let error):
            print("There was an error \(error)")
        case .success(let translated):
            print("The translated string is: \(translated)"
     }
}

Now, you still have the problem of actually updating the Text view on the screen. You would use an @State string property or an @Published property in some model and update that string value and the view will update (You may need to dispatch this onto the main queue).

However, I don't see the value in creating this as an extension on String. Is it really a new behaviour that you want all strings to have? It is probably best implemented as a function in your translation manager object.