wrong range returned while using rangeOfMisspllledWordInString function of UITextChec

Discussion in 'iOS Programming' started by ashwinr87, Sep 28, 2012.

  1. ashwinr87, Sep 28, 2012
    Last edited: Sep 28, 2012

    ashwinr87 macrumors member

    Joined:
    Mar 9, 2011
    #1
    Hi,

    I am using this code to spell check the text I type in my UITextView.
    My code below is similar to the one used in the Spell Check and Word Completion section of apple documentation

    Code:
    - (IBAction)didPressButton:(id)sender
        {
            NSInteger currentOffset = 0;
            NSRange currentRange = NSMakeRange(0, 0);
            NSString *theText = self.textView.text;
            NSRange stringRange = NSMakeRange(0, theText.length-1);
            NSArray *guesses;
            BOOL done = NO;
            NSString *theLanguage = [[UITextChecker availableLanguages] objectAtIndex:0];
        
        if (!theLanguage)
            
            theLanguage = @"en_US";
        
        while (!done)
        {
            currentRange = [self.checker rangeOfMisspelledWordInString:theText range:stringRange
                                                            startingAt:currentOffset wrap:NO language:theLanguage];
            NSLog(@"currentRange : %d", currentRange.location);
            
            if (currentRange.location == NSNotFound)
            {
                done = YES;
                continue;
            }
            
            guesses = [self.checker guessesForWordRange:currentRange inString:theText
                                               language:theLanguage];
            
            NSLog(@"Word misspelled is %@", [theText substringWithRange:currentRange]);
            NSLog(@"Possible replacements are %@", guesses);
            
            self.textView.text = [self.textView.text stringByReplacingCharactersInRange:currentRange
                                                                             withString:[guesses objectAtIndex:0]];
            currentOffset = currentOffset + (currentRange.length-1);
            NSLog(@"currentOffset : %d", currentOffset);
        }
        }
    
    In my UITextChecker, I type in "Thiis is a speell check"

    When I click the button, it calls the didPressButton function and it starts the process of spell checking the string in the UITextView. when it reaches "speell" it throws out a wrong range and it crashes the application. I logged the range and when I had a breakpoint before the if (currentRange ... ) code. looking at the log output, I saw that it returns a wrong range after it does the spell check for "speell".

    The app crashes on the line "self.textView.text = [self.textView.text stringByReplacingCharactersInRange:currentRange withString:[guesses objectAtIndex:0]];"


    I am unable to figure out what is going wrong.
    It would be really great if someone could help me figure this out.
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    What makes you think the range is wrong?

    When the app crashes, what is the run-time error message? What line of code is causing the crash? Details, please.
     
  3. ashwinr87 thread starter macrumors member

    Joined:
    Mar 9, 2011
    #3
    I logged the range and when I had a breakpoint before the if (currentRange ... ) code. looking at the log output, I saw that it returns a wrong range after it does the spell check for "speell".

    The app crashes on the line "self.textView.text = [self.textView.text stringByReplacingCharactersInRange:currentRange withString:[guesses objectAtIndex:0]];"

    I also edited my question with the details.
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Dejo was asking you to post the actual range values you observed that caused you to conclude it was wrong. Debugging, especially debugging by asking for advice, boils down to "Show your evidence". That means show the actual log output, show the actual values of the range, etc.

    Don't just post your conclusions (e.g. "the range is wrong"). Post the evidence that leads to the conclusion (e.g. "the range location is 982, even though the string is only 20 chars").


    Your code has a logic flaw. You do this:
    Code:
            NSString *theText = self.textView.text;
    
    but you don't ever assign a new value to theText, even though you also do this in the loop:
    Code:
            currentRange = [self.checker rangeOfMisspelledWordInString:[COLOR="Red"]theText[/COLOR] range:stringRange
                                                            startingAt:currentOffset wrap:NO language:theLanguage];
    
     ...
            self.textView.text = [[COLOR="red"]self.textView.text[/COLOR] stringByReplacingCharactersInRange:currentRange
                                                                             withString:[guesses objectAtIndex:0]];
    
    After the first replacement occurs, theText and self.textView.text are no longer the same string. So at best you're doing replacement on the wrong text, and at worst, you're doing a spell-check with an NSString you don't own.


    Your code doesn't account for the possibility that guesses has no object at index 0 (empty guesses). It always assumes there is at least 1 guess.


    Finally, this:
    Code:
            if (currentRange.location == NSNotFound)
            {
                done = YES;
                continue;
            }
    
    suggests you would benefit from reviewing how the break keyword works in a loop.
     
  5. ashwinr87 thread starter macrumors member

    Joined:
    Mar 9, 2011
    #5
    Thank you.. I also figured out that I was doing the same mistakes..
     

Share This Page