Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get Spell Check data from an NSString?

I'm writing a simple shift cipher iPhone app as a pet project, and one piece of functionality I'm currently designing is a "universal" decryption of an NSString, that returns an NSArray, all of NSStrings:

- (NSArray*) decryptString: (NSString*)ciphertext{
NSMutableArray* theDecryptions = [NSMutableArray arrayWithCapacity:ALPHABET];

for (int i = 0; i < ALPHABET; ++i) {
    NSString* theNewPlainText = [self decryptString:ciphertext ForShift:i];

    [theDecryptions insertObject:theNewPlainText
                         atIndex:i];
}
return theDecryptions;

}

I'd really like to pass this NSArray into another method that attempts to spell check each individual string within the array, and builds a new array that puts the strings with the fewest typo'd words at lower indicies, so they're displayed first. I'd like to use the system's dictionary like a text field would, so I can match against words that have been trained into the phone by its user.

My current guess is to split a given string up into words, then spell check each with NSSpellChecker's -checkSpellingOfString:StartingAt: and using the number of correct words to sort the Array. Is there an existing library method or well-accepted pattern that would help return such a value for a given string?

like image 720
matthias Avatar asked Nov 06 '22 01:11

matthias


1 Answers

Well, I found a solution that works using UIKit/UITextChecker. It correctly finds the user's most preferred language dictionary, but I'm not sure if it includes learned words in the actual rangeOfMisspelledWords... method. If it doesn't, calling [UITextChecker hasLearnedWord] on currentWord inside the bottom if statement should be enough to find user-taught words.

As noted in the comments, it may be prudent to call rangeOfMisspelledWords with each of the top few languages in [UITextChecker availableLanguages], to help multilingual users.

-(void) checkForDefinedWords {
    NSArray* words = [message componentsSeparatedByString:@" "];
    NSInteger wordsFound = 0;
    UITextChecker* checker = [[UITextChecker alloc] init];
    //get the first language in the checker's memory- this is the user's
    //preferred language.
    //TODO: May want to search with every language (or top few) in the array
    NSString* preferredLang = [[UITextChecker availableLanguages] objectAtIndex:0];

    //for each word in the array, determine whether it is a valid word
    for(NSString* currentWord in words){
        NSRange range;
        range = [checker rangeOfMisspelledWordInString:currentWord
                                                 range:NSMakeRange(0, [currentWord length]) 
                                            startingAt:0 
                                                  wrap:NO
                                              language:preferredLang];

        //if it is valid (no errors found), increment wordsFound
        if (range.location == NSNotFound) {
            //NSLog(@"%@ %@", @"Valid Word found:", currentWord);
            wordsFound++;
        }
        else {
            //NSLog(@"%@ %@", @"Invalid Word found:", currentWord);
        }
    }


    //After all "words" have been searched, save wordsFound to validWordCount
    [self setValidWordCount:wordsFound];

    [checker release];
}
like image 121
matthias Avatar answered Nov 12 '22 16:11

matthias