skip to Main Content

I have developed a speech recognition function that can detect Arabic audio and return a string, I assign it to a var called speechRecogText.

Within the code I also have a text field which I store the input in another string var called textFieldText.

Goal I want to be able to check if the speechRecogText contains wants in the textFieldText, this works normally with English but for Arabic it does not work.

However when I try the opposite way speechRecogText.contains(textFieldText) it works. Code below

    // the two variables
    var speechRecogText: String = ""
    var textFieldText: String = ""

Speech Recognition functions and Textfield… After I enter the inputs I call the function compareTexts()

func compareTexts() {
    
    // Checking the textField text
    if speechRecogText.contains(textFieldText) {
        print("matching texts")
    } else {
        print("not matching")
    }
    
    // Checking the speech recog text
    if textFieldText.contains(speechRecogText) {
        print("matching texts")
    } else {
        print("not matching")
    }
}

For example both would print word "قل" in Arabic. But when I call the function, the console shows (answer):

Console 
//matching texts
//not matching

I want the second one to also work/match and print matching texts.

Although both variables contain similar text the result is a bit confusing. Do they not store same values or is it they show the same stringa but deep in code they vary somehow?

I would really appreciate your support 🙂

Here is the entire code

This is the Entire Code.

import SwiftUI
import SwiftSpeech

struct ContentView: View {
    
    @State var speechRecogText = "قل"
    @State var textFieldText = "قل"
    
    var body: some View {
        
        VStack {
            
            //MARK: - Text Field
                        
            TextField("textfield text", text: $textFieldText)
                .padding()
            
            Button(action: {
                compareTexts()
            } ) {
                ZStack {
                    Color.blue.clipShape(Circle()).frame(width: 70, height: 70)
                    Text("Check").foregroundColor(.white)
                }
            }
            
            
            //MARK: - Speech Recognition
            
            
            Text("speechRecogText: " + speechRecogText)
            
            SwiftSpeech.RecordButton()
                .swiftSpeechRecordOnHold(locale: Locale(identifier: "ar"),
                                         animation: .spring(),
                                         distanceToCancel: 50)

                .onRecognizeLatest { result in
                    self.speechRecogText = result.bestTranscription.formattedString
                    if result.isFinal {
                        print("last transcript")
                    }
                } handleError: { error in
                    print("Failed recognizing the audio. Retry: (error)")
                }
        }
        
    }
    

    func compareTexts() {
        // Checking the textField text
        if speechRecogText.contains(textFieldText) {
            print("---> speechRecogText contains textFieldText")
        } else {
            print("---> speechRecogText DOES NOT contains textFieldText")
        }

        // Checking the speech recog text
        if textFieldText.contains(speechRecogText) {
            print("---> textFieldText contains speechRecogText")
        } else {
            print("---> textFieldText DOES NOT contains speechRecogText")
        }
    }
}

3

Answers


  1. Chosen as BEST ANSWER

    So after testing the code I figured out that the speech recognition text had more characters than the hardcoded string. When I used .count() for the textField text "قل" it printed 2, but for the speech recognition, it had printed 3.

    I used the mapping method to view the extra character.

    speechRecogText.map({ print($0) })
    

    It looked like the first character was an empty space. So I used

    speechRecogText.removeFirst()
    

    and then compared. And the result was as desired.


  2. ok, this is how I tested comparing Arabic texts. It shows the expected results.

     import SwiftUI
    
    @main
    struct TestApp: App {
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
    
    struct ContentView: View {
        @State var results1 = "testing1"
        @State var results2 = "testing2"
        var speechRecogText: String = "قلّ"
        var textFieldText: String = "قلّ جسمه من الكبَر"
        
        func compareTexts() {
            // Checking the textField text
            if speechRecogText.trim().contains(textFieldText.trim()) {
                results1 = "speechRecogText contains textFieldText"
                print("---> speechRecogText contains textFieldText")
            } else {
                results1 = "speechRecogText DOES NOT contains textFieldText"
                print("---> speechRecogText DOES NOT contains textFieldText")
            }
            // Checking the speech recog text
            if textFieldText.trim().contains(speechRecogText.trim()) {
                results2 = "textFieldText contains speechRecogText"
                print("---> textFieldText contains speechRecogText")
            } else {
                results2 = "textFieldText DOES NOT contains speechRecogText"
                print("---> textFieldText DOES NOT contains speechRecogText")
            }
        }
        
        var body: some View {
            VStack (spacing: 50) {
                Text(results1)
                Text(results2)
            }
            .onAppear {
                compareTexts()
            }
        }
    }
    
    extension String {
        func trim() -> String {
            return self.trimmingCharacters(in: .whitespacesAndNewlines)
        }
    }
    
    Login or Signup to reply.
  3. Universal solution for any language

    I noticed that dictation actually appends a nil character, whose unicodeScalar is 65532 or u{fffc}, to the string being processed, making the string unusable for searches. In Arabic it might become the first character because of the string direction.

    extension String {
        func removeNilCharacters() -> String {
            return self.replacingOccurrences(of: "u{fffc}", with: "", options: String.CompareOptions.literal, range: nil)
        }
    }
    

    Applying .removeNilCharacters() to the string returned by a textfield should resolve the issue, whether dictation was invoked or not.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search