Swift – Identify misspelled words and errors in phrases

A simple tutorial for find and identify the wrong typed words of the user in your application using the UITextChecker framework and the NatualLanguage framework.

Final result:


Let’s start!

We use for this tutorial the following new things:

In order to identify the wrong words in your phrase, you need to understand the language of the phrase.

NLLanguageRecognizer helps you to resolve this issue in a very simple way:

private func detectLanguage( phrase: String ) -> NLLanguage? {
     let recognizer = NLLanguageRecognizer()
     recognizer.processString(phrase)
     return recognizer.dominantLanguage
 }

You can pass a phrase on it and get the corresponding language.

let phrase = "This si a text wiht lots of errrors. The scope of this tutorila is to colorizze the wrong wordss."

let phraseLanguage: NLLanguage? = detectLanguage( phrase: phrase )
print( phraseLanguage )

Now we need to check all the words and get, the wrong list words or the range of the words (use it for NSAttributedStrings for instance)

I’ve created a simple struct and a simple checker function, like these:

struct Words {
     var range: NSRange?
     var word:  String
 }

And we use it in the checker:

private func checkMispelledWords( phrase: String ) -> [Words] {
     var rangesOfWords: [Words] = [Words]()

     let phraseLanguage: NLLanguage? = detectLanguage( phrase: phrase )
     guard let language = phraseLanguage else { return rangesOfWords }

     let textChecker = UITextChecker()
     let nsString = NSString(string: phrase)
     let stringRange = NSRange(location: 0, length: nsString.length)
     var offset = 0

     while true {
         let wordRange = textChecker.rangeOfMisspelledWord(
             in: phrase,
             range: stringRange,
             startingAt: offset,
             wrap: false,
             language: language.rawValue)

         guard wordRange.location != NSNotFound else { break }

         let wrongWord = nsString.substring(with: wordRange)
         offset = wordRange.upperBound

         rangesOfWords.append( Words(range: wordRange, word: wrongWord) )
     }
     return rangesOfWords
 }

Now we have a new [Word] array with our data:

let words: [Words] = checkMispelledWords(
                      phrase: textArea.attributedText.string)

If you add a button and a textarea in your app you can attach the attributed string and play with the attributes:

@IBAction func didCheckErrorsPressed(_ sender: Any) {
     let words: [Words] = checkMispelledWords(phrase: textArea.attributedText.string)

     words.forEach {
         print( "Word: ($0.word)" )
         attributedString?.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: $0.range!)
     }

     textArea.attributedText = attributedString
 }

Now you can “coloryze” your text to make the errors in red.

Enjoy writing!

 

Alberto Pasca

Software engineer @ Pirelli & C. S.p.A. with a strong passion for mobile  development, security, and connected things.