iPhone objective-c: detecting a 'real' word
Asked Answered
E

2

9

I need a (quick and dirty) solution to basically detect if a certain NSString is a 'real' word, that is, if it's in the dictionary. So basically, a very simplistic spell checker. Does anyone know of any way to do this? Basically I either need a file containing all words in the English dictionary (which I've searched for, but to no avail), or a way to interface with the iPhones spell checking service. Of course I would like to interface with the iPhones spell check service in a similar way to NSSpellChecker on OSX so my app will work with other languages, but at this point I'll take what I can get.

Lastly, here's some pseudo-code to better illustrate my needs:

-(BOOL)isDictionaryWord:(NSString*)word;  //returns TRUE when word=@"greetings". returns FALSE when word=@"slkfjsdkl";
Eocene answered 28/7, 2011 at 15:1 Comment(6)
Why not just use n NSSpellChecker?Constitutionality
@Wolfgang: like NSObject NSString ....Hexangular
@Wolfgang: NS prefixed classes are available on iOS, like NSObject, NSNumber, NSString, NSPredicate, NSFetchedController, ...Nannana
Ah right, I guess I'm a bit tired after a hard day at work :)Entrails
Seems NSSpellChecker isn't available on iOS though, couldn't find it in Apple's docs (developer site).Entrails
NSSpellChecker isn't available on iOS because it uses UITextChecker instead, as can be seen in @brain's answer.Capitulation
H
21

Use UITextChecker instead. The code below might not be perfect but should give you a good idea.

-(BOOL)isDictionaryWord:(NSString*)word {
    UITextChecker *checker = [[UITextChecker alloc] init];
    NSLocale *currentLocale = [NSLocale currentLocale];
    NSString *currentLanguage = [currentLocale objectForKey:NSLocaleLanguageCode];
    NSRange searchRange = NSMakeRange(0, [word length]);

    NSRange misspelledRange = [checker rangeOfMisspelledWordInString:word range:searchRange startingAt:0 wrap:NO language:currentLanguage];
    return misspelledRange.location == NSNotFound;
}
Hexangular answered 28/7, 2011 at 15:7 Comment(0)
C
3

You can make UITextChecker work accurately without needing to add a new dictionary.

I use a two-step process because I need the first step to be fast (but not accurate). You may only need step two which is the accurate check. Note this makes use of the UITextChecker's completionsForPartialWordRange function which is why it's more accurate than the MisspelledWord function.

//Step one: I quickly check to see if a combination of letters passes the spell check. This is not that accurate but it's very fast so I can quickly exclude lots of letter combinations (brute force approach).

UITextChecker *checker;
NSString *wordToCheck = @"whatever"; // The combination of letters you wish to check

// Set the range to the length of the word
NSRange range = NSMakeRange(0, wordToCheck.length - 1);

NSRange misspelledRange = [checker rangeOfMisspelledWordInString:wordToCheck range: range startingAt:0 wrap:NO language: @"en_US"];
BOOL isRealWord = misspelledRange.location == NSNotFound;

// Call step two, to confirm that this is a real word
if (isRealWord) {
    isRealWord = [self isRealWordOK:wordToCheck];
}
return isRealWord; // if true then we found a real word, if not move to next combination of letters

// Step Two: Extra check to make sure the word is really a real word. returns true if we have a real word.

-(BOOL)isRealWordOK:(NSString *)wordToCheck {

    // we dont want to use any words that the lexicon has learned.
    if ([UITextChecker hasLearnedWord:wordToCheck]) {
        return NO;
    }

    // now we are going to use the word completion function to see if this word really exists, by removing the final letter and then asking auto complete to complete the word, then look through all the results and if its not found then its not a real word. Note the auto complete is very acurate unlike the spell checker.
    NSRange range = NSMakeRange(0, wordToCheck.length - 1);
    NSArray *guesses = [checker completionsForPartialWordRange:range inString:wordToCheck language:@"en_US"];

    // confirm that the word is found in the auto-complete list
    for (NSString *guess in guesses) {

        if ([guess isEqualToString:wordToCheck]) {
            // we found the word in the auto complete list so it's real :-)
            return YES;
        }
    }

    // if we get to here then it's not a real word :-(
    NSLog(@"Word not found in second dictionary check:%@",wordToCheck);
    return NO;

}
Cistern answered 27/2, 2013 at 20:8 Comment(1)
i have followed your code spinets but some of the words like "thy,arouse,white,evil,lover" are real word but UITextchecker is showing as invalid words.Johnnie

© 2022 - 2024 — McMap. All rights reserved.